Sorry for all of the packages. They grew and grew and grew, and I don’t want to refactor everything to reduce the dependencies.
library(raster)
library(data.table)
library(sf)
#RStoolbox has some dependencies like openMP that can be difficult to compile on a Mac (needed for the dependent package "caret"). If you have High Sierra OS or newer, search for instructions specific to your OS- it's a lot easier than older OS's.
library(RStoolbox)
library(leaflet)
library(plotly)
library(gdata)
library(BSDA)
library(ade4)
library(readxl)
library(janitor)
library(rnaturalearth)
library(adehabitatHS)
library(climateStability)
library(htmlwidgets)
library(tidyverse)
library(ggspatial)
library(here)
library(mapview)
library(fs)
r_path <- here::here("R")
source(file.path(r_path, "plot_leaflet_function.R")) #source locality plotting function
source(file.path(r_path, "plot_climate_pca_function.R")) #source pca plotting function
source(file.path(r_path, "species_pca_function.R")) #source function that computes climate pca per species
source(file.path(r_path, "min_convex_poly.R")) #source function that creates a minimum convex polygon around points
source(file.path(r_path, "enfa_calc_function.R"))
source(file.path(r_path, "marginality_lollipop_plot.R"))
source(file.path(r_path, "presence_absence_raster_function.R"))
source(file.path(r_path, "crop_background_env_function.R"))
source(file.path(r_path, "enfa_hex_plot.R"))
source(file.path(r_path, "total_climate_pca_plot.R"))
source(file.path(r_path, "raster_correlation_function.R"))
source(file.path(r_path, "move_to_species.R"))
Create subdirectories (if needed) and establish paths.
# function to check if subfolder exists. If not, make it
create_dir <- function(out_path) {
if (!dir.exists(out_path)) {
dir.create(out_path)
} else
print("Directory already there.")
}
# path for interactive plots, maps, etc. output
interactive_path <- here::here("output", "interactive_plots")
create_dir(precip_path)
# temperature climate data
temp_path <-
here::here("data",
"climate",
"paleoclim_late_pleistocene",
"temperature")
create_dir(temp_path)
# precipitation climate data
precip_path <-
here::here("data",
"climate",
"paleoclim_late_pleistocene",
"precipitation")
create_dir(precip_path)
# raster output
raster_path <-
here::here("output",
"rasters")
create_dir(raster_path)
# map (non-interactive) output
map_path <- here::here("output", "maps")
create_dir(map_path)
# plot (non-interactive) output
plot_path <- here::here("output", "plots")
create_dir(plot_path)
# spreadsheet output
spread_path <- here::here("output", "spreadsheets")
create_dir(spread_path)
# R object (e.g. .RDS files) output
obj_path <- here::here("output", "objects")
create_dir(obj_path)
Read in the spreadsheet and take a look at the data.
# data path
loc_path <- here::here("data", "all species New_6-14-19.xlsx")
### read in spreadsheet
loc <- read_xlsx(loc_path) %>%
janitor::clean_names() %>%
mutate(reproductive_mode = as.factor(reproductive_mode))
#get the number of individuals, and the sexuality counts per species
count_repro_mode <- loc %>%
group_by(genus, species, reproductive_mode) %>%
dplyr::count() %>%
mutate(genus_species = str_c(genus, species, sep = "_"),
genus_species = str_replace_all(genus_species, " ", "_"),
genus_species = str_replace_all(genus_species, "\\.", "")) %>%
ungroup() %>%
mutate(genus_species = fct_reorder(genus_species, n, sum)) %>%
ggplot(aes(x = genus_species, y = n, fill = reproductive_mode)) +
geom_col() +
coord_flip() +
theme_minimal()
count_repro_mode
Map
Plot a leaflet map of the localities. The leaflet map is interactive. You can click on the localities and a flag with some metadata will pop up!
PCA-Genera
Climate Data
Read in the bioclim layers for analysis. I’m using all 19 for this preliminary exploration. I’m using CHELSA v1.2 data downloaded from their website. Plotting the first temperature layer to take a look at the data.
PCA by locality
This is a PCA of the climate data extracted for each locality, rather than a PCA of the total climate space. This gives us a general idea of differences in environmental niche.
Run the pca and check out variable loadings and proportion of variance explained by components.
#extract data from chelsa for each locality. Making this into a data frame with columns labeled so the row labeling lines up after I remove the NAs.
#extract data from worldclim for each locality.
coords <- data.frame(latitude = loc$longitude, longitude = loc$latitude)
loc_clim <- dplyr::bind_cols(loc, raster::extract(w, coords, method = "simple", df = TRUE)) %>%
drop_na(bio1) %>%
dplyr::select(-ID)
#make a matrix of only bioclim values
clim_mat <- loc_clim[,grep("bio", names(loc_clim))] %>% as.matrix()
#run pca on climate variables
clim_pca <- prcomp(clim_mat, scale = TRUE)
summary_pca <- summary(clim_pca) #check out the components
#plot tables
summary_pca
knitr::kable(round(clim_pca$rotation[,1:3],3)) #Table of loading scores for the first 3 PCs.
Two plots: One plot of the PCA colored according to genus, with convex hulls surrounding the genera. It looks like this reflects a latitudinal gradient in temperature! You can interact with the PCA plot by clicking on points to view associated metadata. You can isolate the genus you want to view by double clicking the genus in the legend! You can also remove a genus by clicking on it once. There’s some other functionality you can explore in the toolbar at the top of the plot. The second plot is a PCA colored according to reproductive mode. It looks like asexual populations occupy slightly larger niche space, but both reproductive modes have a similar niche center.
#add pca results to loc_clim data frame
loc_clim <- data.frame(loc_clim, clim_pca$x)
#use sourced plot_clim_pca function to plot the pca results. args are the data set with species names and PC axis values and the pca summary
all_pca <- plot_clim_pca(loc_clim, summary_pca, factor = "genus")
all_pca
#use sourced plot_clim_pca function to plot the pca results. args are the data set with species names and PC axis values and the pca summary
repro_pca <-
plot_clim_pca(loc_clim, summary_pca, factor = "reproductive_mode")
repro_pca
# save the plot colored by genus
htmlwidgets::saveWidget(
all_pca,
file.path(interactive_path, "all_species_pca_genus.html"),
selfcontained = TRUE
)
# save the plot colored by reproductive mode
htmlwidgets::saveWidget(
repro_pca,
file.path(interactive_path, "all_species_pca_repro.html"),
selfcontained = TRUE
)
Examining whether asexual populations occupy more unstable climates than sexual populations. Only using species with multiple sexual and asexual populations. Asexual pops tend to occupy more stable temperature environments, but less stable precipitation environments. We’re estimating stability using the method presented by Owens and Guralnick 2019- climateStability: AN R PACKAGE TO ESTIMATE CLIMATE STABILITY FROM TIME-SLICE CLIMATOLOGIES.
### Creating temperature and precipitation stability layers
### Using bio1 (average temp) and bio12 (average precip)
### 2.5 arcmin resolution, already cropped to NZ to speed up computation time
#time slices are calculated as the difference between the midpoints of the two time periods the climate layers were calculated for (e.g. midpoint of LH = (4.2 ka - 0.3 ka) / 2 + 0.3 ka = 2.25, midpoint of MH = (8.326 ka - 4.2 ka) / 2 + 4.2 = 6.263. time_slice = 6.263 - 2.25 = 4.013)
time_slices <- c(2550, 4013, 6037, 1500, 2050, 5150)
precip_deviation <-
climateStability::deviationThroughTime(variableDirectory = precip_path, timeSlicePeriod = time_slices)
precip_stability <- (1 / precip_deviation)
precip_stability_scaled <- climateStability::rescale0to1(precip_stability)
# write precipitation stability to file
writeRaster(
precip_stability_scaled,
filename = file.path(raster_path, "precip_stability_scaled.tif"),
format = "GTiff"
)
temp_deviation <-
climateStability::deviationThroughTime(variableDirectory = temp_path, timeSlicePeriod = time_slices)
temp_stability <- (1 / temp_deviation)
temp_stability_scaled <- climateStability::rescale0to1(temp_stability)
# write temperature stability to file
writeRaster(
temp_stability_scaled,
filename = file.path(raster_path, "temp_stability_scaled.tif"),
format = "GTiff"
)
overall_stability_scaled <- precip_stability_scaled * temp_stability_scaled
# write overall stability to file
writeRaster(
overall_stability_scaled,
filename = file.path(raster_path, "overall_stability_scaled.tif"),
format = "GTiff"
)
temp_stability_map <- ggplot() +
ggspatial::layer_spatial(data = temp_stability_scaled) +
labs(title = "Temperature stability") +
scale_fill_viridis_c(na.value = "transparent") +
theme_minimal()
precip_stability_map <- ggplot() +
ggspatial::layer_spatial(data = precip_stability_scaled) +
labs(title = "Precipitation stability") +
scale_fill_viridis_c(na.value = "transparent") +
theme_minimal()
overall_stability_map <- ggplot() +
ggspatial::layer_spatial(data = overall_stability_scaled) +
labs(title = "Overall stability") +
scale_fill_viridis_c(na.value = "transparent") +
theme_minimal()
temp_stability_map
precip_stability_map
overall_stability_map
ggsave("temp_stability.png",
plot = temp_stability_map,
device = "png",
path = map_path,
dpi = "retina")
ggsave("precip_stability.png",
plot = precip_stability_map,
device = "png",
path = map_path,
dpi = "retina")
ggsave("overall_stability.png",
plot = overall_stability_map,
device = "png",
path = map_path,
dpi = "retina")
Plot stability across species.
# filter for relevant species and asexual reproductive mode
asexual_locs <- loc %>%
mutate(lat_long = str_c(latitude, longitude)) %>%
filter(
reproductive_mode == "asexual",
species == "horridus" |
species == "jucundum" |
species == "hookeri" |
species == "annulata" |
species == "ovobessus" |
species == "huttoni",
!duplicated(lat_long)
) %>%
dplyr::select(longitude, latitude)
# filter for relevant species and sexual reproductive mode
sexual_locs <- loc %>%
mutate(lat_long = str_c(latitude, longitude)) %>%
filter(
reproductive_mode == "sexual",
species == "horridus" |
species == "jucundum" |
species == "hookeri" |
species == "annulata" |
species == "ovobessus" |
species == "huttoni",
!duplicated(lat_long)
) %>%
dplyr::select(longitude, latitude)
# extract preciptitation values and bind into a new dataframe
precip_asexual <-
raster::extract(precip_stability_scaled, asexual_locs) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
precip_sexual <-
raster::extract(precip_stability_scaled, sexual_locs) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
precip_df <- bind_rows(precip_asexual, precip_sexual)
# plot precipitation stability
precip_stability_plot <- ggplot(
data = precip_df,
aes(x = reproductive_mode, y = precip_stability_scaled, fill = reproductive_mode)
) +
geom_violin(width = 0.8) +
geom_boxplot(width = 0.1,
color = "gray",
fill = "transparent") +
scale_fill_viridis_d(option = "magma") +
theme_dark()
precip_stability_plot
# extract temperature values and bind into a new data frame
temp_asexual <-
raster::extract(temp_stability_scaled, asexual_locs) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
temp_sexual <-
raster::extract(temp_stability_scaled, sexual_locs) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
temp_df <- bind_rows(temp_asexual, temp_sexual)
# plot temperature stability
temp_stability_plot <- ggplot(data = temp_df,
aes(x = reproductive_mode, y = temp_stability_scaled, fill = reproductive_mode)) +
geom_violin(width = 0.8) +
geom_boxplot(width = 0.1,
color = "gray",
fill = "transparent") +
scale_fill_viridis_d(option = "magma") +
theme_dark()
temp_stability_plot
# extract overall stability values and bind into a dataframe
overall_asexual <-
raster::extract(overall_stability_scaled, asexual_locs) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
overall_sexual <-
raster::extract(overall_stability_scaled, sexual_locs) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
overall_df <- bind_rows(overall_asexual, overall_sexual)
# plot overall stability
overall_stability_plot <- ggplot(
data = overall_df,
aes(x = reproductive_mode, y = overall_stability_scaled, fill = reproductive_mode)
) +
geom_violin(width = 0.8) +
geom_boxplot(width = 0.1,
color = "gray",
fill = "transparent") +
scale_fill_viridis_d(option = "magma") +
theme_dark()
overall_stability_plot
ggsave("temp_stability_plot.png",
plot = temp_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
ggsave("precip_stability_plot.png",
plot = precip_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
ggsave("overall_stability_plot.png",
plot = overall_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
PCA-Species
These are PCAs of environmental space for species within genera. Each climate PCA is of localities for a single genus, colored by species. I’m doing this even for genera with one species, so it’s easy to see if certain localities group together.
Acanthoxyla
#source function to conduct a PCA on individual species
summary_list_acan <- species_pca_fun(loc_clim, "acanthoxyla")
#plot
acan_plot <- plot_clim_pca(summary_list_acan$loc_clim, summary_list_acan$summary_pca, "reproductive_mode")
acan_plot
# save pca plot
htmlwidgets::saveWidget(acan_plot, file.path(interactive_path, "acanthoxyla_pca.html"), selfcontained = TRUE)
#filter localities for the focal genus
acan_loc <- loc %>%
filter(genus == "acanthoxyla")
#use sourced plot_locs_leaflet script to plot localities
acan_map <- plot_locs_leaflet(acan_loc, "reproductive_mode")
acan_map
# save the map
mapview::mapshot(acan_map, url = file.path(interactive_path, "acan_map.html"), file = file.path(interactive_path,"acan_map.pdf"))
Argosarchus
# conduct pca
summary_list_argo <- species_pca_fun(loc_clim, "argosarchus")
# plot
argo_plot <-
plot_clim_pca(summary_list_argo$loc_clim,
summary_list_argo$summary_pca,
factor = "reproductive_mode")
argo_plot
htmlwidgets::saveWidget(argo_plot,
file.path(interactive_path, "ahor_pca.html"),
selfcontained = TRUE)
#filter localities for the focal genus
argo_loc <- loc %>%
filter(genus == "argosarchus")
#use sourced plot_locs_leaflet script to plot localities
argo_map <- plot_locs_leaflet(argo_loc, "reproductive_mode")
argo_map
mapview::mapshot(
argo_map,
url = file.path(interactive_path, "ahor_map.html"),
file = file.path(interactive_path, "ahor_map.pdf")
)
Now I’m going to to environmental niche factor analysis between sexual and asexual populations within the species.
#get background env't for the species
ahor_bg_env <- bg_env_crop(argo_loc,
species = "horridus",
environment = w,
buffer = 0.5)
#enfa for the sexual species
ahor_sexual_enfa <- enfa_calc_fun(locs = argo_loc,
species = "horridus",
reproductive_mode = "sexual",
mask_raster = ahor_bg_env)
#enfa for the asexual species
ahor_asexual_enfa <- enfa_calc_fun(locs = argo_loc,
species = "horridus",
reproductive_mode = "asexual",
mask_raster = ahor_bg_env)
#plot the marginality scores
ahor_marginality <- marginality_lollipop(sex_marg = ahor_sexual_enfa$m,
asex_marg = ahor_asexual_enfa$m,
full_species_name = "Argosarchus horridus")
# write scores to csvs
readr::write_csv(
ahor_asexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "ahor_asexual_marginality_score.csv")
)
readr::write_csv(
ahor_sexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "ahor_sexual_marginality_score.csv")
)
ggsave("ahor_marginality_lollipop.png",
plot = ahor_marginality,
device = "png",
path = plot_path,
dpi = "retina")
A couple different ways to visualize the environmental variation. 1) Scatterplot visualizations of marginality vs axis 1 of the specialization with the labels removed (they make things indiscernable). Red = occupied e-space. Gray = Background e-space. The yellow dot indicates the mean marginality (it’s not the value that is on the lollipop plot, so don’t let that confuse you). 2) ENFA histogram visualizations of marginality and specialization axes. 3) PCA of total e-space with colors corresponding to sexual vs. asexual populations.
### 1) ENFA scatterplot
#access the relevant values for plotting
ahor_asexual_df <- ahor_asexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = ahor_asexual_enfa$pr)
readr::write_csv(ahor_asexual_df,
file.path(spread_path, "ahor_asexual_marginality_df.csv"))
ahor_sexual_df <- ahor_sexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = ahor_sexual_enfa$pr)
readr::write_csv(ahor_sexual_df,
file.path(spread_path, "ahor_sexual_marginality_df.csv"))
#asexual
ahor_enfa_spec_asexual <- enfa_hex_plot(ahor_asexual_df, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ahor_enfa_spec_asexual
ggsave("ahor_enfa_spec_asexual.png",
plot = ahor_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
#sexual
ahor_enfa_spec_sexual <- enfa_hex_plot(ahor_sexual_df, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ahor_enfa_spec_sexual
ggsave("ahor_enfa_spec_sexual.png",
plot = ahor_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
## asexual
hist(ahor_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
# write to file
png(filename = file.path(plot_path, "ahor_asexual_enfa_hist.png"))
hist(ahor_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
dev.off()
## sexual
hist(ahor_sexual_enfa)
title(main = "Sexual", adj = 0.7, line = -12)
# write to file
png(filename = file.path(plot_path, "ahor_sexual_enfa_hist.png"))
hist(ahor_sexual_enfa)
title(main = "Sexual", adj = 0.7, line = -12)
dev.off()
### 3) PCA of total e-space
ahor_total_pca <- total_climate_pca_plot(bg_env = ahor_bg_env, locs = argo_loc, genus = "Argosarchus", species = "horridus")
ahor_total_pca
ggsave("ahor_total_pca.png",
plot = ahor_total_pca,
device = "png",
path = plot_path,
dpi = "retina")
Trying out a repeat of the analyses with reduced environmental space. Prioritizing variables that will limit their distribution (i.e. variables that represent the extremes). After correlation analysis, we’re left with BIO6, BIO13, BIO14, BIO16
Repeat the analysis with the reduced data set. The background environment is 0.5 degrees, a ballpark dispersal limitation for all stick insect species in this study.
w_ahor <- raster::subset(w, c("bio6", "bio13", "bio14", "bio16"))
#get background env't for the species
ahor_bg_env_subset <- bg_env_crop(argo_loc,
species = "horridus",
environment = w_ahor,
buffer = 0.5)
#enfa for the sexual species
ahor_sexual_enfa_subset <- enfa_calc_fun(locs = argo_loc,
species = "horridus",
reproductive_mode = "sexual",
mask_raster = ahor_bg_env_subset)
#enfa for the asexual species
ahor_asexual_enfa_subset <- enfa_calc_fun(locs = argo_loc,
species = "horridus",
reproductive_mode = "asexual",
mask_raster = ahor_bg_env_subset)
# write marginality scores to csv
readr::write_csv(
ahor_asexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "ahor_subset_asexual_marginality_score.csv")
)
readr::write_csv(
ahor_sexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "ahor_subset_sexual_marginality_score.csv")
)
#plot the marginality scores
ahor_subset_marginality <-
marginality_lollipop(
sex_marg = ahor_sexual_enfa_subset$m,
asex_marg = ahor_asexual_enfa_subset$m,
full_species_name = "Argosarchus horridus"
)
ahor_subset_marginality
ggsave("ahor_subset_marginality.png",
plot = ahor_subset_marginality,
device = "png",
path = plot_path,
dpi = "retina")
Visualize with reduced data set
### 1) ENFA scatterplot
#access the relevant values for plotting
ahor_asexual_df_subset <- ahor_asexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = ahor_asexual_enfa_subset$pr)
readr::write_csv(
ahor_asexual_df_subset,
file.path(spread_path, "ahor_subset_asexual_marginality_df.csv")
)
ahor_sexual_df_subset <- ahor_sexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = ahor_sexual_enfa_subset$pr)
readr::write_csv(
ahor_sexual_df_subset,
file.path(spread_path, "ahor_subset_sexual_marginality_df.csv")
)
#asexual. Jesus these variable names are getting long
ahor_subset_enfa_spec_asexual <-
enfa_hex_plot(
ahor_asexual_df_subset,
marg = Mar,
spec = Spe1,
repro_mode = "Asexual"
)
ahor_subset_enfa_spec_asexual
ggsave(
"ahor_subset_enfa_spec_asexual.png",
plot = ahor_subset_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina"
)
# sexual
ahor_subset_enfa_spec_sexual <-
enfa_hex_plot(
ahor_sexual_df_subset,
marg = Mar,
spec = Spe1,
repro_mode = "Sexual"
)
ahor_subset_enfa_spec_sexual
ggsave(
"ahor_subset_enfa_spec_sexual.png",
plot = ahor_subset_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina"
)
### 2) ENFA histogram
# asexual
hist(ahor_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "ahor_subset_asexual_enfa_hist.png"))
hist(ahor_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
dev.off()
# sexual
hist(ahor_sexual_enfa_subset)
title(main = "Sexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "ahor_subset_sexual_enfa_hist.png"))
hist(ahor_sexual_enfa_subset)
title(main = "Sexual", adj = 0.7, line = -12)
dev.off()
### 3) PCA of total e-space
ahor_subset_total_pca <-
total_climate_pca_plot(
bg_env = ahor_bg_env_subset,
locs = argo_loc,
genus = "Argosarchus",
species = "horridus"
)
ahor_subset_total_pca
ggsave(
"ahor_subset_total_pca.png",
plot = ahor_subset_total_pca,
device = "png",
path = plot_path,
dpi = "retina"
)
# save enfa objects and remove them from the environment. They take up a lot of memory.
saveRDS(ahor_sexual_enfa, file = file.path(obj_path, "ahor_sexual_enfa.RDS"))
rm(ahor_sexual_enfa)
saveRDS(ahor_asexual_enfa, file = file.path(obj_path, "ahor_asexual_enfa.RDS"))
rm(ahor_asexual_enfa)
saveRDS(ahor_sexual_enfa_subset,
file = file.path(obj_path, "ahor_subset_sexual_enfa.RDS"))
rm(ahor_sexual_enfa_subset)
saveRDS(ahor_asexual_enfa_subset,
file = file.path(obj_path, "ahor_subset_asexual_enfa.RDS"))
rm(ahor_asexual_enfa_subset)
We’re also interested in seeing if asexual populations live in more unstable climatic areas relative to sexual populations.
argo_locs_asexual <- argo_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "asexual",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
argo_locs_sexual <- argo_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "sexual",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
precip_asexual_ahor <- raster::extract(precip_stability_scaled, argo_locs_asexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
precip_sexual_ahor <- raster::extract(precip_stability_scaled, argo_locs_sexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
precip_df_ahor <- bind_rows(precip_asexual_ahor, precip_sexual_ahor)
readr::write_csv(precip_df_ahor,
file.path(spread_path, "ahor_precip_stability_df.csv"))
ahor_precip_stability_plot <- ggplot(data = precip_df_ahor, aes(x = reproductive_mode, y = precip_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
ahor_precip_stability_plot
ggsave(
"ahor_precip_stability.png",
plot = ahor_precip_stability_plot,
device = "png",
path = plot_path,
dpi = "retina"
)
temp_asexual_ahor <- raster::extract(temp_stability_scaled, argo_locs_asexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
temp_sexual_ahor <- raster::extract(temp_stability_scaled, argo_locs_sexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
temp_df_ahor <- bind_rows(temp_asexual_ahor, temp_sexual_ahor)
readr::write_csv(temp_df_ahor,
file.path(spread_path, "ahor_temp_stability_df.csv"))
ahor_temp_stability_plot <- ggplot(data = temp_df_ahor, aes(x = reproductive_mode, y = temp_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
ahor_temp_stability_plot
ggsave(
"ahor_temp_stability.png",
plot = ahor_temp_stability_plot,
device = "png",
path = plot_path,
dpi = "retina"
)
overall_asexual_ahor <- raster::extract(overall_stability_scaled, argo_locs_asexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
overall_sexual_ahor <- raster::extract(overall_stability_scaled, argo_locs_sexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
overall_df_ahor <- bind_rows(overall_asexual_ahor, overall_sexual_ahor)
readr::write_csv(overall_df_ahor,
file.path(spread_path, "ahor_overall_stability_df.csv"))
ahor_overall_stability_plot <- ggplot(data = overall_df_ahor, aes(x = reproductive_mode, y = overall_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
ahor_overall_stability_plot
ggsave(
"ahor_overall_stability.png",
plot = ahor_overall_stability_plot,
device = "png",
path = plot_path,
dpi = "retina"
)
Put all output into species-specific subfolders.
Asteliaphasma
#pca
summary_list_aste <- species_pca_fun(loc_clim, "asteliaphasma")
#plot
aste_plot <- plot_clim_pca(summary_list_aste$loc_clim, summary_list_aste$summary_pca, factor = "reproductive_mode")
aste_plot
#if selfcontained = TRUE, you can remove the folder that gets added alongside the plot.
htmlwidgets::saveWidget(aste_plot, file.path(interactive_path, "asteliaphasma_pca.html"), selfcontained = TRUE)
#filter localities for the focal genus
aste_loc <- loc %>%
filter(genus == "asteliaphasma")
#use sourced plot_locs_leaflet script to plot localities
aste_map <- plot_locs_leaflet(aste_loc, "reproductive_mode")
aste_map
# save the map
mapview::mapshot(aste_map, url = file.path(interactive_path, "aste_map.html"), file = file.path(interactive_path, "aste_map.pdf"))
Now I’m going to to environmental niche factor analysis between sexual and asexual populations within the species.
#get background env't for the species
ajuc_bg_env <- bg_env_crop(aste_loc,
species = "jucundum",
environment = w,
buffer = 0.5)
#enfa for the sexual species
ajuc_sexual_enfa <- enfa_calc_fun(locs = aste_loc,
species = "jucundum",
reproductive_mode = "sexual",
mask_raster = ajuc_bg_env)
#enfa for the asexual species
ajuc_asexual_enfa <- enfa_calc_fun(locs = aste_loc,
species = "jucundum",
reproductive_mode = "asexual",
mask_raster = ajuc_bg_env)
#plot the marginality scores
ajuc_marginality <- marginality_lollipop(sex_marg = ajuc_sexual_enfa$m,
asex_marg = ajuc_asexual_enfa$m,
full_species_name = "Asteliaphasma jucundum")
ajuc_marginality
# write scores to csvs
readr::write_csv(
ajuc_asexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "ajuc_asexual_marginality_score.csv")
)
readr::write_csv(
ajuc_sexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "ajuc_sexual_marginality_score.csv")
)
ggsave("ajuc_marginality_lollipop.png",
plot = ajuc_marginality,
device = "png",
path = plot_path,
dpi = "retina")
A couple different ways to visualize the environmental variation. 1) Scatterplot visualizations of marginality vs axis 1 of the specialization with the labels removed (they make things indiscernable). Red = occupied e-space. Gray = Background e-space. 2) ENFA histogram visualizations of marginality and specialization axes. 3) PCA of total e-space with colors corresponding to sexual vs. asexual populations.
### 1) ENFA scatterplot
#access the relevant values for plotting
ajuc_asexual_df <- ajuc_asexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = ajuc_asexual_enfa$pr)
readr::write_csv(ajuc_asexual_df,
file.path(spread_path, "ajuc_asexual_marginality_df.csv"))
ajuc_sexual_df <- ajuc_sexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = ajuc_sexual_enfa$pr)
readr::write_csv(ajuc_sexual_df,
file.path(spread_path, "ajuc_sexual_marginality_df.csv"))
#asexual
ajuc_enfa_spec_asexual <- enfa_hex_plot(ajuc_asexual_df, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("ajuc_enfa_spec_asexual.png",
plot = ajuc_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
#sexual
ajuc_enfa_spec_sexual <- enfa_hex_plot(ajuc_sexual_df, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("ajuc_enfa_spec_sexual.png",
plot = ajuc_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
#asexual
hist(ajuc_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "ajuc_asexual_enfa_hist.png"))
hist(ajuc_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
dev.off()
# sexual
hist(ajuc_sexual_enfa)
title(main = "Sexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "ajuc_sexual_enfa_hist.png"))
hist(ajuc_sexual_enfa)
title(main = "Sexual", adj = 0.7, line = -12)
dev.off()
### 3) PCA of total e-space
ajuc_total_pca <- total_climate_pca_plot(bg_env = ajuc_bg_env, locs = aste_loc, genus = "Asteliophasma", species = "jucundum")
ajuc_total_pca
ggsave("ajuc_total_pca.png",
plot = ajuc_total_pca,
device = "png",
path = plot_path,
dpi = "retina")
Trying out a repeat of the analyses with reduced environmental space. Prioritizing variables that will limit their distribution (i.e. variables that represent the extremes). After correlation analysis, we’re left with BIO5, BIO6, BIO14, BIO17.
Repeat the analysis with the reduced data set.
w_ajuc <- raster::subset(w, c("bio5", "bio6", "bio14", "bio17"))
#get background env't for the species
ajuc_bg_env_subset <- bg_env_crop(aste_loc,
species = "jucundum",
environment = w_ajuc,
buffer = 0.5)
#enfa for the sexual species
ajuc_sexual_enfa_subset <- enfa_calc_fun(locs = aste_loc,
species = "jucundum",
reproductive_mode = "sexual",
mask_raster = ajuc_bg_env_subset)
#enfa for the asexual species
ajuc_asexual_enfa_subset <- enfa_calc_fun(locs = aste_loc,
species = "jucundum",
reproductive_mode = "asexual",
mask_raster = ajuc_bg_env_subset)
# write marginality scores to csv
readr::write_csv(
ajuc_asexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "ajuc_subset_asexual_marginality_score.csv")
)
readr::write_csv(
ajuc_sexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "ajuc_subset_sexual_marginality_score.csv")
)
# plot the marginality scores
ajuc_subset_marginality <-
marginality_lollipop(
sex_marg = ajuc_sexual_enfa_subset$m,
asex_marg = ajuc_asexual_enfa_subset$m,
full_species_name = "Asteliaphasma jucundum"
)
ajuc_subset_marginality
ggsave("ajuc_subset_marginality.png",
plot = ajuc_subset_marginality,
device = "png",
path = plot_path,
dpi = "retina")
Visualize with the reduced data set.
### 1) ENFA scatterplot
# access the relevant values for plotting
ajuc_asexual_df_subset <- ajuc_asexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = ajuc_asexual_enfa_subset$pr)
readr::write_csv(
ajuc_asexual_df_subset,
file.path(spread_path, "ajuc_asexual_df_subset.csv")
)
ajuc_sexual_df_subset <- ajuc_sexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = ajuc_sexual_enfa_subset$pr)
readr::write_csv(
ajuc_sexual_df_subset,
file.path(spread_path, "ajuc_sexual_df_subset.csv")
)
# asexual
ajuc_subset_enfa_spec_asexual <- enfa_hex_plot(ajuc_asexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("ajuc_subset_enfa_spec_asexual.png",
plot = ajuc_subset_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
# sexual
ajuc_subset_enfa_spec_sexual <- enfa_hex_plot(ajuc_sexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("ajuc_subset_enfa_spec_sexual.png",
plot = ajuc_subset_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
# asexual
hist(ajuc_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "ajuc_subset_asexual_enfa_hist.png"))
hist(ajuc_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
dev.off()
# sexual
hist(ajuc_sexual_enfa_subset)
title(main = "Sexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "ajuc_subset_sexual_enfa_hist.png"))
hist(ajuc_sexual_enfa_subset)
title(main = "Sexual", adj = 0.7, line = -12)
dev.off()
### 3) PCA of total e-space
ajuc_subset_total_pca <- total_climate_pca_plot(bg_env = ajuc_bg_env_subset, locs = aste_loc, genus = "Asteliaphasma", species = "jucundum")
ggsave("ajuc_subset_total_pca.png",
plot = ajuc_subset_total_pca,
device = "png",
path = plot_path,
dpi = "retina")
# save enfa objects and remove them from the environment. They take up a lot of memory.
saveRDS(ajuc_sexual_enfa, file = file.path(obj_path, "ajuc_sexual_enfa.RDS"))
rm(ajuc_sexual_enfa)
saveRDS(ajuc_asexual_enfa, file = file.path(obj_path, "ajuc_asexual_enfa.RDS"))
rm(ajuc_asexual_enfa)
saveRDS(ajuc_sexual_enfa_subset,
file = file.path(obj_path, "ajuc_subset_sexual_enfa.RDS"))
rm(ajuc_sexual_enfa_subset)
saveRDS(ajuc_asexual_enfa_subset,
file = file.path(obj_path, "ajuc_subset_asexual_enfa.RDS"))
rm(ajuc_asexual_enfa_subset)
We’re also interested in seeing if asexual populations live in more unstable climatic areas relative to sexual populations.
aste_locs_asexual <- aste_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "asexual",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
aste_locs_sexual <- aste_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "sexual",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
precip_asexual_ajuc <- raster::extract(precip_stability_scaled, aste_locs_asexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
precip_sexual_ajuc <- raster::extract(precip_stability_scaled, aste_locs_sexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
precip_df_ajuc <- bind_rows(precip_asexual_ajuc, precip_sexual_ajuc)
readr::write_csv(precip_df_ajuc,
file.path(spread_path, "ajuc_precip_stability_df.csv"))
ajuc_precip_stability_plot <- ggplot(data = precip_df_ajuc, aes(x = reproductive_mode, y = precip_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
ggsave("ajuc_precip_stability.png",
plot = ajuc_precip_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
temp_asexual_ajuc <- raster::extract(temp_stability_scaled, aste_locs_asexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
temp_sexual_ajuc <- raster::extract(temp_stability_scaled, aste_locs_sexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
temp_df_ajuc <- bind_rows(temp_asexual_ajuc, temp_sexual_ajuc)
readr::write_csv(temp_df_ajuc,
file.path(spread_path, "ajuc_temp_stability_df.csv"))
ajuc_temp_stability_plot <- ggplot(data = temp_df_ajuc, aes(x = reproductive_mode, y = temp_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
ggsave("ajuc_precip_stability.png",
plot = ajuc_temp_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
overall_asexual_ajuc <- raster::extract(overall_stability_scaled, aste_locs_asexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
overall_sexual_ajuc <- raster::extract(overall_stability_scaled, aste_locs_sexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
overall_df_ajuc <- bind_rows(overall_asexual_ajuc, overall_sexual_ajuc)
readr::write_csv(overall_df_ajuc,
file.path(spread_path, "ajuc_overall_stability_df.csv"))
ajuc_overall_stability_plot <- ggplot(data = overall_df_ajuc, aes(x = reproductive_mode, y = overall_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
ggsave("ajuc_overall_stability.png",
plot = ajuc_overall_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
Put all output into species-specific subfolders.
Clitarchus
summary_list_clita <- species_pca_fun(loc_clim, "Clitarchus")
clita_plot <- plot_clim_pca(summary_list_clita$loc_clim, summary_list_clita$summary_pca, factor = "reproductive_mode")
clita_plot
htmlwidgets::saveWidget(clita_plot, file.path(interactive_path, "Clitarchus_pca.html"), selfcontained = TRUE)
#filter localities for the focal genus
clita_loc <- loc %>%
filter(genus == "Clitarchus")
#use sourced plot_locs_leaflet script to plot localities
clita_map <- plot_locs_leaflet(clita_loc, "reproductive_mode")
clita_map
# save the map
mapview::mapshot(
clita_map,
url = file.path(interactive_path, "clita_map.html"),
file = paste0(file.path(interactive_path, "clita_map.pdf"))
)
Now I’m going to perform environmental niche factor analysis with sexual and asexual populations within the species.
#get background env't for the species
choo_bg_env <- bg_env_crop(
clita_loc,
species = "hookeri",
environment = w,
buffer = 0.5
)
#enfa for the sexual species
choo_sexual_enfa <- enfa_calc_fun(
locs = clita_loc,
species = "hookeri",
reproductive_mode = "sexual",
mask_raster = choo_bg_env
)
#enfa for the asexual species
choo_asexual_enfa <- enfa_calc_fun(
locs = clita_loc,
species = "hookeri",
reproductive_mode = "asexual",
mask_raster = choo_bg_env
)
# write scores to csvs
readr::write_csv(
choo_asexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "choo_asexual_marginality_score.csv")
)
readr::write_csv(
choo_sexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "choo_sexual_marginality_score.csv")
)
#plot the marginality scores
choo_marginality <-
marginality_lollipop(
sex_marg = choo_sexual_enfa$m,
asex_marg = choo_asexual_enfa$m,
full_species_name = "Clitarchus hookeri"
)
choo_marginality
ggsave(
"choo_marginality_lollipop.png",
plot = choo_marginality,
device = "png",
path = plot_path,
dpi = "retina"
)
A couple different ways to visualize the environmental variation. 1) Scatterplot visualizations of marginality vs axis 1 of the specialization with the labels removed (they make things indiscernable). Red = occupied e-space. Gray = Background e-space. 2) ENFA histogram visualizations of marginality and specialization axes. 3) PCA of total e-space with colors corresponding to sexual vs. asexual populations.
### 1) ENFA scatterplot
#access the relevant values for plotting
choo_asexual_df <- choo_asexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = choo_asexual_enfa$pr)
readr::write_csv(choo_asexual_df,
file.path(spread_path, "choo_asexual_marginality_df.csv"))
choo_sexual_df <- choo_sexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = choo_sexual_enfa$pr)
readr::write_csv(choo_sexual_df,
file.path(spread_path, "choo_sexual_marginality_df.csv"))
# asexual
choo_enfa_spec_asexual <- enfa_hex_plot(choo_asexual_df, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("choo_enfa_spec_asexual.png",
plot = choo_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
#sexual
choo_enfa_spec_sexual <- enfa_hex_plot(choo_sexual_df, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("choo_enfa_spec_sexual.png",
plot = choo_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
#asexual
hist(choo_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "choo_asexual_enfa_hist.png"))
hist(choo_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
dev.off()
#sexual
hist(choo_sexual_enfa)
title(main = "Sexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "choo_sexual_enfa_hist.png"))
hist(choo_sexual_enfa)
title(main = "Sexual", adj = 0.7, line = -12)
dev.off()
### 3) PCA of total e-space
choo_total_pca <- total_climate_pca_plot(bg_env = choo_bg_env, locs = clita_loc, genus = "Clitarchus", species = "hookeri")
choo_total_pca
ggsave("choo_total_pca.png",
plot = choo_total_pca,
device = "png",
path = plot_path,
dpi = "retina")
Trying out a repeat of the analyses with reduced environmental space. Prioritizing variables that will limit their distribution (i.e. variables that represent the extremes). After correlation analysis, we’re left with BIO8, BIO11, BIO15, BIO17.
Repeat the analysis with the reduced data set.
w_choo <- raster::subset(w, c("bio8", "bio11", "bio15", "bio17"))
#get background env't for the species
choo_bg_env_subset <- bg_env_crop(clita_loc,
species = "hookeri",
environment = w_choo,
buffer = 0.5)
#enfa for the sexual species
choo_sexual_enfa_subset <- enfa_calc_fun(locs = clita_loc,
species = "hookeri",
reproductive_mode = "sexual",
mask_raster = choo_bg_env_subset)
#enfa for the asexual species
choo_asexual_enfa_subset <- enfa_calc_fun(locs = clita_loc,
species = "hookeri",
reproductive_mode = "asexual",
mask_raster = choo_bg_env_subset)
# write marginality scores to csv
readr::write_csv(
choo_asexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "choo_subset_asexual_marginality_score.csv")
)
readr::write_csv(
choo_sexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "choo_subset_sexual_marginality_score.csv")
)
# plot the marginality scores
choo_subset_marginality <-
marginality_lollipop(
sex_marg = choo_sexual_enfa_subset$m,
asex_marg = choo_asexual_enfa_subset$m,
full_species_name = "Clitarchus hookeri"
)
choo_subset_marginality
ggsave("choo_subset_marginality.png",
plot = choo_subset_marginality,
device = "png",
path = plot_path,
dpi = "retina")
Visualize with the reduced data set.
### 1) ENFA scatterplot
# access the relevant values for plotting
choo_asexual_df_subset <- choo_asexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = choo_asexual_enfa_subset$pr)
readr::write_csv(
choo_asexual_df_subset,
file.path(spread_path, "choo_asexual_df_subset.csv")
)
choo_sexual_df_subset <- choo_sexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = choo_sexual_enfa_subset$pr)
readr::write_csv(
choo_sexual_df_subset,
file.path(spread_path, "choo_sexual_df_subset.csv")
)
# asexual
choo_subset_enfa_spec_asexual <- enfa_hex_plot(choo_asexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("choo_subset_enfa_spec_asexual.png",
plot = choo_subset_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
# sexual
choo_subset_enfa_spec_sexual <- enfa_hex_plot(choo_sexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("choo_subset_enfa_spec_sexual.png",
plot = choo_subset_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
# asexual
hist(choo_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "choo_subset_asexual_enfa_hist.png"))
hist(choo_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
dev.off()
# sexual
hist(choo_sexual_enfa_subset)
title(main = "Sexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "choo_subset_sexual_enfa_hist.png"))
hist(choo_sexual_enfa_subset)
title(main = "Sexual", adj = 0.7, line = -12)
dev.off()
### 3) PCA of total e-space
choo_subset_total_pca <- total_climate_pca_plot(bg_env = choo_bg_env_subset, locs = clita_loc, genus = "Clitarchus", species = "hookeri")
choo_subset_total_pca
ggsave("choo_subset_total_pca.png",
plot = choo_subset_total_pca,
device = "png",
path = plot_path,
dpi = "retina")
# save enfa objects and remove them from the environment. They take up a lot of memory.
saveRDS(choo_sexual_enfa, file = file.path(obj_path, "choo_sexual_enfa.RDS"))
rm(choo_sexual_enfa)
saveRDS(choo_asexual_enfa, file = file.path(obj_path, "choo_asexual_enfa.RDS"))
rm(choo_asexual_enfa)
saveRDS(choo_sexual_enfa_subset,
file = file.path(obj_path, "choo_subset_sexual_enfa.RDS"))
rm(choo_sexual_enfa_subset)
saveRDS(choo_asexual_enfa_subset,
file = file.path(obj_path, "choo_subset_asexual_enfa.RDS"))
rm(choo_asexual_enfa_subset)
We’re also interested in seeing if asexual populations live in more unstable climatic areas relative to sexual populations.
clita_locs_asexual <- clita_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "asexual",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
clita_locs_sexual <- clita_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "sexual",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
precip_asexual_choo <- raster::extract(precip_stability_scaled, clita_locs_asexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
precip_sexual_choo <- raster::extract(precip_stability_scaled, clita_locs_sexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
precip_df_choo <- bind_rows(precip_asexual_choo, precip_sexual_choo)
readr::write_csv(precip_df_choo,
file.path(spread_path, "choo_precip_stability_df.csv"))
choo_precip_stability_plot <- ggplot(data = precip_df_choo, aes(x = reproductive_mode, y = precip_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
choo_precip_stability_plot
ggsave("choo_precip_stability.png",
plot = choo_precip_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
temp_asexual_choo <- raster::extract(temp_stability_scaled, clita_locs_asexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
temp_sexual_choo <- raster::extract(temp_stability_scaled, clita_locs_sexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
temp_df_choo <- bind_rows(temp_asexual_choo, temp_sexual_choo)
readr::write_csv(temp_df_choo,
file.path(spread_path, "choo_temp_stability_df.csv"))
choo_temp_stability_plot <- ggplot(data = temp_df_choo, aes(x = reproductive_mode, y = temp_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
choo_temp_stability_plot
ggsave("choo_precip_stability.png",
plot = choo_temp_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
overall_asexual_choo <- raster::extract(overall_stability_scaled, clita_locs_asexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
overall_sexual_choo <- raster::extract(overall_stability_scaled, clita_locs_sexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
overall_df_choo <- bind_rows(overall_asexual_choo, overall_sexual_choo)
readr::write_csv(overall_df_choo,
file.path(spread_path, "choo_overall_stability_df.csv"))
choo_overall_stability_plot <- ggplot(data = overall_df_choo, aes(x = reproductive_mode, y = overall_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
choo_overall_stability_plot
ggsave("choo_overall_stability.png",
plot = choo_overall_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")
Put all output into species-specific subfolders.
Micrarchus
summary_list_micra <- species_pca_fun(loc_clim, "micrarchus")
micra_plot <- plot_clim_pca(summary_list_micra$loc_clim, summary_list_micra$summary_pca, factor = "reproductive_mode")
micra_plot
# if selfcontained = TRUE, you can remove the folder that gets added alongside the plot.
htmlwidgets::saveWidget(micra_plot,
file.path(interactive_path, "micrarchus_pca.html"),
selfcontained = TRUE)
#filter localities for the focal genus
micra_loc <- loc %>%
filter(genus == "micrarchus")
#use sourced plot_locs_leaflet script to plot localities
micra_map <- plot_locs_leaflet(micra_loc, "reproductive_mode")
micra_map
# save the map
mapview::mapshot(micra_map, url = file.path(interactive_path, "micra_map.html"), file = file.path(interactive_path, "micra_map.pdf"))
Niveaphasma
summary_list_nive <- species_pca_fun(loc_clim, "niveaphasma")
nive_plot <- plot_clim_pca(summary_list_nive$loc_clim, summary_list_nive$summary_pca, factor = "reproductive_mode")
nive_plot
# save the plot
htmlwidgets::saveWidget(nive_plot, file.path(interactive_path, "niveaphasma_pca.html"), selfcontained = TRUE)
#filter localities for the focal genus
nive_loc <- loc %>%
filter(genus == "niveaphasma")
#use sourced plot_locs_leaflet script to plot localities
nive_map <- plot_locs_leaflet(nive_loc, "reproductive_mode")
nive_map
# save the map
mapview::mapshot(nive_map, url = file.path(interactive_path, "nive_map.html"), file = file.path(interactive_path, "nive_map.pdf"))
Now I’m going to perform environmental niche factor analysis with sexual and asexual populations within the species.
# get background env't for the species
nive_bg_env <- bg_env_crop(
nive_loc,
species = "annulata",
environment = w,
buffer = 0.5
)
#enfa for the sexual species
nive_sexual_enfa <- enfa_calc_fun(
locs = nive_loc,
species = "annulata",
reproductive_mode = "sexual",
mask_raster = nive_bg_env
)
#enfa for the asexual species
nive_asexual_enfa <- enfa_calc_fun(
locs = nive_loc,
species = "annulata",
reproductive_mode = "asexual",
mask_raster = nive_bg_env
)
# write scores to csvs
readr::write_csv(
nive_asexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "nive_asexual_marginality_score.csv")
)
readr::write_csv(
nive_sexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "nive_sexual_marginality_score.csv")
)
#plot the marginality scores
nive_marginality <-
marginality_lollipop(
sex_marg = nive_sexual_enfa$m,
asex_marg = nive_asexual_enfa$m,
full_species_name = "Niveaphasma annulata"
)
nive_marginality
ggsave(
"nive_marginality_lollipop.png",
plot = nive_marginality,
device = "png",
path = plot_path,
dpi = "retina"
)
A couple different ways to visualize the environmental variation. 1) Scatterplot visualizations of marginality vs axis 1 of the specialization with the labels removed (they make things indiscernable). Red = occupied e-space. Gray = Background e-space. 2) ENFA histogram visualizations of marginality and specialization axes. 3) PCA of total e-space with colors corresponding to sexual vs. asexual populations.
### 1) ENFA scatterplot
#access the relevant values for plotting
nive_asexual_df <- nive_asexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = nive_asexual_enfa$pr)
readr::write_csv(nive_asexual_df,
file.path(spread_path, "nive_asexual_marginality_df.csv"))
nive_sexual_df <- nive_sexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = nive_sexual_enfa$pr)
readr::write_csv(nive_sexual_df,
file.path(spread_path, "nive_sexual_marginality_df.csv"))
# asexual
nive_enfa_spec_asexual <- enfa_hex_plot(nive_asexual_df, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("nive_enfa_spec_asexual.png",
plot = nive_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
#sexual
nive_enfa_spec_sexual <- enfa_hex_plot(nive_sexual_df, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("nive_enfa_spec_sexual.png",
plot = nive_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
#asexual
hist(nive_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "nive_asexual_enfa_hist.png"))
hist(nive_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
dev.off()
#sexual
hist(nive_sexual_enfa)
title(main = "Sexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "nive_sexual_enfa_hist.png"))
hist(nive_sexual_enfa)
title(main = "Sexual", adj = 0.7, line = -12)
dev.off()
### 3) PCA of total e-space
nive_total_pca <- total_climate_pca_plot(bg_env = nive_bg_env, locs = nive_loc, genus = "Niveaphasma", species = "annulata")
nive_total_pca
ggsave("nive_total_pca.png",
plot = nive_total_pca,
device = "png",
path = plot_path,
dpi = "retina")
Trying out a repeat of the analyses with reduced environmental space. Prioritizing variables that will limit their distribution (i.e. variables that represent the extremes). After correlation analysis, we’re left with BIO4, BIO8, BIO9, BIO11, BIO15, BIO17
Repeat the analysis with the reduced data set.
w_nive <- raster::subset(w, c("bio4", "bio8", "bio9", "bio11", "bio15", "bio17"))
#get background env't for the species
nive_bg_env_subset <- bg_env_crop(nive_loc,
species = "annulata",
environment = w_nive,
buffer = 0.5)
#enfa for the sexual species
nive_sexual_enfa_subset <- enfa_calc_fun(locs = nive_loc,
species = "annulata",
reproductive_mode = "sexual",
mask_raster = nive_bg_env_subset)
#enfa for the asexual species
nive_asexual_enfa_subset <- enfa_calc_fun(locs = nive_loc,
species = "annulata",
reproductive_mode = "asexual",
mask_raster = nive_bg_env_subset)
# write marginality scores to csv
readr::write_csv(
nive_asexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "nive_subset_asexual_marginality_score.csv")
)
readr::write_csv(
nive_sexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "nive_subset_sexual_marginality_score.csv")
)
# plot the marginality scores
nive_subset_marginality <-
marginality_lollipop(
sex_marg = nive_sexual_enfa_subset$m,
asex_marg = nive_asexual_enfa_subset$m,
full_species_name = "Niveaphasma annulata"
)
nive_subset_marginality
ggsave("nive_subset_marginality.png",
plot = nive_subset_marginality,
device = "png",
path = plot_path,
dpi = "retina")
Visualize with the reduced data set.
### 1) ENFA scatterplot
# access the relevant values for plotting
nive_asexual_df_subset <- nive_asexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = nive_asexual_enfa_subset$pr)
readr::write_csv(
nive_asexual_df_subset,
file.path(spread_path, "nive_asexual_df_subset.csv")
)
nive_sexual_df_subset <- nive_sexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = nive_sexual_enfa_subset$pr)
readr::write_csv(
nive_sexual_df_subset,
file.path(spread_path, "nive_sexual_df_subset.csv")
)
# asexual
nive_subset_enfa_spec_asexual <- enfa_hex_plot(nive_asexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("nive_subset_enfa_spec_asexual.png",
plot = nive_subset_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
# sexual
nive_subset_enfa_spec_sexual <- enfa_hex_plot(nive_sexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("nive_subset_enfa_spec_sexual.png",
plot = nive_subset_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
# asexual
hist(nive_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "nive_subset_asexual_enfa_hist.png"))
hist(nive_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
dev.off()
# sexual
hist(nive_sexual_enfa_subset)
title(main = "Sexual", adj = 0.7, line = -12)
png(filename = file.path(plot_path, "nive_subset_sexual_enfa_hist.png"))
hist(nive_sexual_enfa_subset)
title(main = "Sexual", adj = 0.7, line = -12)
dev.off()
### 3) PCA of total e-space
nive_subset_total_pca <- total_climate_pca_plot(bg_env = nive_bg_env_subset, locs = nive_loc, genus = "Niveaphasma", species = "annulata")
nive_subset_total_pca
ggsave("nive_subset_total_pca.png",
plot = nive_subset_total_pca,
device = "png",
path = plot_path,
dpi = "retina")
# save enfa objects and remove them from the environment. They take up a lot of memory.
saveRDS(nive_sexual_enfa, file = file.path(obj_path, "nive_sexual_enfa.RDS"))
rm(nive_sexual_enfa)
saveRDS(nive_asexual_enfa, file = file.path(obj_path, "nive_asexual_enfa.RDS"))
rm(nive_asexual_enfa)
saveRDS(nive_sexual_enfa_subset,
file = file.path(obj_path, "nive_subset_sexual_enfa.RDS"))
rm(nive_sexual_enfa_subset)
saveRDS(nive_asexual_enfa_subset,
file = file.path(obj_path, "nive_subset_asexual_enfa.RDS"))
rm(nive_asexual_enfa_subset)
We’re also interested in seeing if asexual populations live in more unstable climatic areas relative to sexual populations.
nive_locs_asexual <- nive_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "asexual",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
nive_locs_sexual <- nive_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "sexual",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
precip_asexual_nive <- raster::extract(precip_stability_scaled, nive_locs_asexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
precip_sexual_nive <- raster::extract(precip_stability_scaled, nive_locs_sexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
precip_df_nive <- bind_rows(precip_asexual_nive, precip_sexual_nive)
readr::write_csv(precip_df_nive,
file.path(spread_path, "nive_precip_stability_df.csv"))
nive_precip_stability_plot <- ggplot(data = precip_df_nive, aes(x = reproductive_mode, y = precip_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
nive_precip_stability_plot
ggsave("nive_precip_stability.png",
plot = nive_precip_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")

temp_asexual_nive <- raster::extract(temp_stability_scaled, nive_locs_asexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
temp_sexual_nive <- raster::extract(temp_stability_scaled, nive_locs_sexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
temp_df_nive <- bind_rows(temp_asexual_nive, temp_sexual_nive)
readr::write_csv(temp_df_nive,
file.path(spread_path, "nive_temp_stability_df.csv"))
nive_temp_stability_plot <- ggplot(data = temp_df_nive, aes(x = reproductive_mode, y = temp_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
nive_temp_stability_plot
ggsave("nive_precip_stability.png",
plot = nive_temp_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")

overall_asexual_nive <- raster::extract(overall_stability_scaled, nive_locs_asexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
overall_sexual_nive <- raster::extract(overall_stability_scaled, nive_locs_sexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
overall_df_nive <- bind_rows(overall_asexual_nive, overall_sexual_nive)
readr::write_csv(overall_df_nive,
file.path(spread_path, "nive_overall_stability_df.csv"))
nive_overall_stability_plot <- ggplot(data = overall_df_nive, aes(x = reproductive_mode, y = overall_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
nive_overall_stability_plot
ggsave("nive_overall_stability.png",
plot = nive_overall_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")

Put all output into species-specific subfolders.
nive_out_int_path <- file.path(interactive_path, "niveaphasma_annulata")
nive_out_plot_path <- file.path(plot_path, "niveaphasma_annulata")
nive_out_spread_path <- file.path(spread_path, "niveaphasma_annulata")
nive_out_obj_path <- file.path(obj_path, "niveaphasma_annulata")
# move interactive
move_to_species(in_path = interactive_path,
out_path = nive_out_int_path,
pattern = "nive")
# move plots
move_to_species(in_path = plot_path,
out_path = nive_out_plot_path,
pattern = "nive")
# move spreadsheets
move_to_species(in_path = spread_path,
out_path = nive_out_spread_path,
pattern = "nive")
# move objects
move_to_species(in_path = obj_path,
out_path = nive_out_obj_path,
pattern = "nive")
Spinotectarchus
Assuming "longitude" and "latitude" are longitude and latitude, respectively
Importance of components:
PC1 PC2 PC3 PC4
Standard deviation 3.2695 2.2059 1.34553 0.86655
Proportion of Variance 0.5626 0.2561 0.09529 0.03952
Cumulative Proportion 0.5626 0.8187 0.91400 0.95352
PC5 PC6 PC7 PC8
Standard deviation 0.74273 0.46863 0.17686 0.16724
Proportion of Variance 0.02903 0.01156 0.00165 0.00147
Cumulative Proportion 0.98255 0.99411 0.99576 0.99723
PC9 PC10 PC11 PC12
Standard deviation 0.13032 0.11326 0.10151 0.07549
Proportion of Variance 0.00089 0.00068 0.00054 0.00030
Cumulative Proportion 0.99813 0.99880 0.99934 0.99964
PC13 PC14 PC15 PC16
Standard deviation 0.05244 0.04105 0.03104 0.02296
Proportion of Variance 0.00014 0.00009 0.00005 0.00003
Cumulative Proportion 0.99979 0.99988 0.99993 0.99995
PC17 PC18 PC19
Standard deviation 0.02110 0.01685 0.01122
Proportion of Variance 0.00002 0.00001 0.00001
Cumulative Proportion 0.99998 0.99999 1.00000
| bio1 |
-0.279 |
-0.111 |
-0.222 |
| bio10 |
-0.273 |
-0.057 |
-0.287 |
| bio11 |
-0.277 |
-0.149 |
-0.177 |
| bio12 |
0.243 |
-0.262 |
-0.125 |
| bio13 |
0.200 |
-0.325 |
-0.111 |
| bio14 |
0.246 |
-0.230 |
-0.069 |
| bio15 |
-0.133 |
-0.273 |
-0.034 |
| bio16 |
0.209 |
-0.314 |
-0.127 |
| bio17 |
0.254 |
-0.217 |
-0.105 |
| bio18 |
0.231 |
-0.236 |
-0.143 |
| bio19 |
0.216 |
-0.303 |
-0.134 |
| bio2 |
0.199 |
0.274 |
-0.319 |
| bio3 |
0.174 |
0.238 |
-0.438 |
| bio4 |
0.225 |
0.267 |
-0.029 |
| bio5 |
-0.165 |
0.138 |
-0.577 |
| bio6 |
-0.274 |
-0.193 |
-0.055 |
| bio7 |
0.217 |
0.281 |
-0.234 |
| bio8 |
-0.272 |
-0.165 |
-0.177 |
| bio9 |
-0.206 |
-0.046 |
-0.144 |
Tectarchus
Assuming "longitude" and "latitude" are longitude and latitude, respectively
Importance of components:
PC1 PC2 PC3 PC4
Standard deviation 2.8207 2.5946 1.6199 0.97671
Proportion of Variance 0.4188 0.3543 0.1381 0.05021
Cumulative Proportion 0.4188 0.7731 0.9112 0.96139
PC5 PC6 PC7 PC8
Standard deviation 0.5929 0.41322 0.34989 0.24011
Proportion of Variance 0.0185 0.00899 0.00644 0.00303
Cumulative Proportion 0.9799 0.98888 0.99532 0.99836
PC9 PC10 PC11 PC12
Standard deviation 0.1152 0.08270 0.06439 0.04904
Proportion of Variance 0.0007 0.00036 0.00022 0.00013
Cumulative Proportion 0.9991 0.99942 0.99964 0.99976
PC13 PC14 PC15 PC16
Standard deviation 0.03772 0.03410 0.02871 0.02481
Proportion of Variance 0.00007 0.00006 0.00004 0.00003
Cumulative Proportion 0.99984 0.99990 0.99994 0.99997
PC17 PC18 PC19
Standard deviation 0.01599 0.01130 0.01040
Proportion of Variance 0.00001 0.00001 0.00001
Cumulative Proportion 0.99999 0.99999 1.00000
| bio1 |
0.333 |
0.031 |
-0.196 |
| bio10 |
0.310 |
0.021 |
-0.288 |
| bio11 |
0.345 |
0.031 |
-0.113 |
| bio12 |
0.050 |
-0.380 |
0.020 |
| bio13 |
0.071 |
-0.367 |
0.088 |
| bio14 |
0.032 |
-0.379 |
-0.011 |
| bio15 |
0.101 |
0.106 |
0.274 |
| bio16 |
0.072 |
-0.368 |
0.077 |
| bio17 |
0.029 |
-0.379 |
-0.010 |
| bio18 |
0.020 |
-0.378 |
-0.015 |
| bio19 |
0.083 |
-0.352 |
0.080 |
| bio2 |
-0.279 |
-0.061 |
-0.354 |
| bio3 |
-0.251 |
-0.056 |
-0.361 |
| bio4 |
-0.300 |
-0.047 |
-0.286 |
| bio5 |
0.215 |
-0.009 |
-0.481 |
| bio6 |
0.351 |
0.044 |
-0.020 |
| bio7 |
-0.284 |
-0.063 |
-0.344 |
| bio8 |
0.274 |
0.009 |
-0.209 |
| bio9 |
0.293 |
0.048 |
-0.198 |
Tectarchus ovobessus
Now I’m going to perform environmental niche factor analysis with sexual and asexual populations within the species.
# get background env't for the species
tect_ovo_bg_env <- bg_env_crop(
tect_loc,
species = "ovobessus",
environment = w,
buffer = 0.5
)
#enfa for the sexual species
tect_ovo_sexual_enfa <- enfa_calc_fun(
locs = tect_loc,
species = "ovobessus",
reproductive_mode = "sexual",
mask_raster = tect_ovo_bg_env
)
#enfa for the asexual species
tect_ovo_asexual_enfa <- enfa_calc_fun(
locs = tect_loc,
species = "ovobessus",
reproductive_mode = "asexual",
mask_raster = tect_ovo_bg_env
)
# write scores to csvs
readr::write_csv(
tect_ovo_asexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "tect_ovo_asexual_marginality_score.csv")
)
readr::write_csv(
tect_ovo_sexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "tect_ovo_sexual_marginality_score.csv")
)
#plot the marginality scores
tect_ovo_marginality <-
marginality_lollipop(
sex_marg = tect_ovo_sexual_enfa$m,
asex_marg = tect_ovo_asexual_enfa$m,
full_species_name = "Tectarchus ovobessus"
)
tect_ovo_marginality
ggsave(
"tect_ovo_marginality_lollipop.png",
plot = tect_ovo_marginality,
device = "png",
path = plot_path,
dpi = "retina"
)

A couple different ways to visualize the environmental variation. 1) Scatterplot visualizations of marginality vs axis 1 of the specialization with the labels removed (they make things indiscernable). Red = occupied e-space. Gray = Background e-space. 2) ENFA histogram visualizations of marginality and specialization axes. 3) PCA of total e-space with colors corresponding to sexual vs. asexual populations.
### 1) ENFA scatterplot
#access the relevant values for plotting
tect_ovo_asexual_df <- tect_ovo_asexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = tect_ovo_asexual_enfa$pr)
readr::write_csv(tect_ovo_asexual_df,
file.path(spread_path, "tect_ovo_asexual_marginality_df.csv"))
tect_ovo_sexual_df <- tect_ovo_sexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = tect_ovo_sexual_enfa$pr)
readr::write_csv(tect_ovo_sexual_df,
file.path(spread_path, "tect_ovo_sexual_marginality_df.csv"))
# asexual
tect_ovo_enfa_spec_asexual <- enfa_hex_plot(tect_ovo_asexual_df, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("tect_ovo_enfa_spec_asexual.png",
plot = tect_ovo_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
#sexual
tect_ovo_enfa_spec_sexual <- enfa_hex_plot(tect_ovo_sexual_df, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("tect_ovo_enfa_spec_sexual.png",
plot = tect_ovo_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
#asexual
hist(tect_ovo_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
quartz_off_screen
2

quartz_off_screen
2


Trying out a repeat of the analyses with reduced environmental space. Prioritizing variables that will limit their distribution (i.e. variables that represent the extremes). After correlation analysis, we’re left with BIO4, BIO8, BIO11, BIO15, BIO17
| bio1 |
bio9 |
0.7683085 |
| bio1 |
bio5 |
0.9431235 |
| bio10 |
bio9 |
0.7649972 |
| bio10 |
bio5 |
0.9696441 |
| bio10 |
bio1 |
0.9949074 |
| bio11 |
bio9 |
0.7840988 |
| bio11 |
bio5 |
0.9097998 |
| bio11 |
bio1 |
0.9941228 |
| bio11 |
bio10 |
0.9798860 |
| bio6 |
bio9 |
0.7634527 |
| bio6 |
bio5 |
0.8549377 |
| bio6 |
bio1 |
0.9774484 |
| bio6 |
bio10 |
0.9527160 |
| bio6 |
bio11 |
0.9924265 |
| bio12 |
bio19 |
0.9303682 |
| bio13 |
bio19 |
0.9494262 |
| bio13 |
bio12 |
0.9904545 |
| bio16 |
bio19 |
0.9503474 |
| bio16 |
bio12 |
0.9911887 |
| bio16 |
bio13 |
0.9993100 |
| bio18 |
bio19 |
0.8488702 |
| bio18 |
bio12 |
0.9765329 |
| bio18 |
bio13 |
0.9544060 |
| bio18 |
bio16 |
0.9557642 |
| bio14 |
bio19 |
0.8939441 |
| bio14 |
bio12 |
0.9862519 |
| bio14 |
bio13 |
0.9664429 |
| bio14 |
bio16 |
0.9680861 |
| bio14 |
bio18 |
0.9878180 |
| bio17 |
bio19 |
0.8861880 |
| bio17 |
bio12 |
0.9881415 |
| bio17 |
bio13 |
0.9676936 |
| bio17 |
bio16 |
0.9693849 |
| bio17 |
bio18 |
0.9875497 |
| bio17 |
bio14 |
0.9958281 |
| bio4 |
bio6 |
-0.8042062 |
| bio2 |
bio3 |
0.9469371 |
| bio2 |
bio4 |
0.8977292 |
| bio7 |
bio3 |
0.8829596 |
| bio7 |
bio4 |
0.9549837 |
| bio7 |
bio2 |
0.9835939 |

Repeat the analysis with the reduced data set.
w_tect_ovo <- raster::subset(w, c("bio4", "bio8", "bio11", "bio15", "bio17"))
#get background env't for the species
tect_ovo_bg_env_subset <- bg_env_crop(tect_loc,
species = "ovobessus",
environment = w_tect_ovo,
buffer = 0.5)
#enfa for the sexual species
tect_ovo_sexual_enfa_subset <- enfa_calc_fun(locs = tect_loc,
species = "ovobessus",
reproductive_mode = "sexual",
mask_raster = tect_ovo_bg_env_subset)
#enfa for the asexual species
tect_ovo_asexual_enfa_subset <- enfa_calc_fun(locs = tect_loc,
species = "ovobessus",
reproductive_mode = "asexual",
mask_raster = tect_ovo_bg_env_subset)
# write marginality scores to csv
readr::write_csv(
tect_ovo_asexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "tect_ovo_subset_asexual_marginality_score.csv")
)
readr::write_csv(
tect_ovo_sexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "tect_ovo_subset_sexual_marginality_score.csv")
)
# plot the marginality scores
tect_ovo_subset_marginality <-
marginality_lollipop(
sex_marg = tect_ovo_sexual_enfa_subset$m,
asex_marg = tect_ovo_asexual_enfa_subset$m,
full_species_name = "Tectarchus ovobessus"
)
tect_ovo_subset_marginality
ggsave("tect_ovo_subset_marginality.png",
plot = tect_ovo_subset_marginality,
device = "png",
path = plot_path,
dpi = "retina")

Visualize with the reduced data set.
### 1) ENFA scatterplot
# access the relevant values for plotting
tect_ovo_asexual_df_subset <- tect_ovo_asexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = tect_ovo_asexual_enfa_subset$pr)
readr::write_csv(
tect_ovo_asexual_df_subset,
file.path(spread_path, "tect_ovo_asexual_df_subset.csv")
)
tect_ovo_sexual_df_subset <- tect_ovo_sexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = tect_ovo_sexual_enfa_subset$pr)
readr::write_csv(
tect_ovo_sexual_df_subset,
file.path(spread_path, "tect_ovo_sexual_df_subset.csv")
)
# asexual
tect_ovo_subset_enfa_spec_asexual <- enfa_hex_plot(tect_ovo_asexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("tect_ovo_subset_enfa_spec_asexual.png",
plot = tect_ovo_subset_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
# sexual
tect_ovo_subset_enfa_spec_sexual <- enfa_hex_plot(tect_ovo_sexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("tect_ovo_subset_enfa_spec_sexual.png",
plot = tect_ovo_subset_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
# asexual
hist(tect_ovo_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
quartz_off_screen
2

quartz_off_screen
2


We’re also interested in seeing if asexual populations live in more unstable climatic areas relative to sexual populations.
tect_ovo_locs_asexual <- tect_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "asexual",
species == "ovobessus",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
tect_ovo_locs_sexual <- tect_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "sexual",
species == "ovobessus",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
precip_asexual_tect_ovo <- raster::extract(precip_stability_scaled, tect_ovo_locs_asexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
precip_sexual_tect_ovo <- raster::extract(precip_stability_scaled, tect_ovo_locs_sexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
precip_df_tect_ovo <- bind_rows(precip_asexual_tect_ovo, precip_sexual_tect_ovo)
readr::write_csv(precip_df_tect_ovo,
file.path(spread_path, "tect_ovo_precip_stability_df.csv"))
tect_ovo_precip_stability_plot <- ggplot(data = precip_df_tect_ovo, aes(x = reproductive_mode, y = precip_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
tect_ovo_precip_stability_plot
ggsave("tect_ovo_precip_stability.png",
plot = tect_ovo_precip_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")

temp_asexual_tect_ovo <- raster::extract(temp_stability_scaled, tect_ovo_locs_asexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
temp_sexual_tect_ovo <- raster::extract(temp_stability_scaled, tect_ovo_locs_sexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
temp_df_tect_ovo <- bind_rows(temp_asexual_tect_ovo, temp_sexual_tect_ovo)
readr::write_csv(temp_df_tect_ovo,
file.path(spread_path, "tect_ovo_temp_stability_df.csv"))
tect_ovo_temp_stability_plot <- ggplot(data = temp_df_tect_ovo, aes(x = reproductive_mode, y = temp_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
tect_ovo_temp_stability_plot
ggsave("tect_ovo_precip_stability.png",
plot = tect_ovo_temp_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")

overall_asexual_tect_ovo <- raster::extract(overall_stability_scaled, tect_ovo_locs_asexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
overall_sexual_tect_ovo <- raster::extract(overall_stability_scaled, tect_ovo_locs_sexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
overall_df_tect_ovo <- bind_rows(overall_asexual_tect_ovo, overall_sexual_tect_ovo)
readr::write_csv(overall_df_tect_ovo,
file.path(spread_path, "tect_ovo_overall_stability_df.csv"))
tect_ovo_overall_stability_plot <- ggplot(data = overall_df_tect_ovo, aes(x = reproductive_mode, y = overall_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
tect_ovo_overall_stability_plot
ggsave("tect_ovo_overall_stability.png",
plot = tect_ovo_overall_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")

Put all output into species-specific subfolders.
tect_ovo_out_int_path <- file.path(interactive_path, "tectarchus_ovobessus")
tect_ovo_out_plot_path <- file.path(plot_path, "tectarchus_ovobessus")
tect_ovo_out_spread_path <- file.path(spread_path, "tectarchus_ovobessus")
tect_ovo_out_obj_path <- file.path(obj_path, "tectarchus_ovobessus")
# move interactive
move_to_species(in_path = interactive_path,
out_path = tect_ovo_out_int_path,
pattern = "tect_ovo")
# move plots
move_to_species(in_path = plot_path,
out_path = tect_ovo_out_plot_path,
pattern = "tect_ovo")
# move spreadsheets
move_to_species(in_path = spread_path,
out_path = tect_ovo_out_spread_path,
pattern = "tect_ovo")
# move objects
move_to_species(in_path = obj_path,
out_path = tect_ovo_out_obj_path,
pattern = "tect_ovo")
Tectarchus huttoni
Now I’m going to perform environmental niche factor analysis with sexual and asexual populations within the species.
# get background env't for the species
tect_hutt_bg_env <- bg_env_crop(
tect_loc,
species = "huttoni",
environment = w,
buffer = 0.5
)
#enfa for the sexual species
tect_hutt_sexual_enfa <- enfa_calc_fun(
locs = tect_loc,
species = "huttoni",
reproductive_mode = "sexual",
mask_raster = tect_hutt_bg_env
)
#enfa for the asexual species
tect_hutt_asexual_enfa <- enfa_calc_fun(
locs = tect_loc,
species = "huttoni",
reproductive_mode = "asexual",
mask_raster = tect_hutt_bg_env
)
# write scores to csvs
readr::write_csv(
tect_hutt_asexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "tect_hutt_asexual_marginality_score.csv")
)
readr::write_csv(
tect_hutt_sexual_enfa$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "tect_hutt_sexual_marginality_score.csv")
)
#plot the marginality scores
tect_hutt_marginality <-
marginality_lollipop(
sex_marg = tect_hutt_sexual_enfa$m,
asex_marg = tect_hutt_asexual_enfa$m,
full_species_name = "Tectarchus huttoni"
)
tect_hutt_marginality
ggsave(
"tect_hutt_marginality_lollipop.png",
plot = tect_hutt_marginality,
device = "png",
path = plot_path,
dpi = "retina"
)

A couple different ways to visualize the environmental variation. 1) Scatterplot visualizations of marginality vs axis 1 of the specialization with the labels removed (they make things indiscernable). Red = occupied e-space. Gray = Background e-space. 2) ENFA histogram visualizations of marginality and specialization axes. 3) PCA of total e-space with colors corresponding to sexual vs. asexual populations.
### 1) ENFA scatterplot
#access the relevant values for plotting
tect_hutt_asexual_df <- tect_hutt_asexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = tect_hutt_asexual_enfa$pr)
readr::write_csv(tect_hutt_asexual_df,
file.path(spread_path, "tect_hutt_asexual_marginality_df.csv"))
tect_hutt_sexual_df <- tect_hutt_sexual_enfa$li %>%
as_tibble() %>%
bind_cols(pr = tect_hutt_sexual_enfa$pr)
readr::write_csv(tect_hutt_sexual_df,
file.path(spread_path, "tect_hutt_sexual_marginality_df.csv"))
# asexual
tect_hutt_enfa_spec_asexual <- enfa_hex_plot(tect_hutt_asexual_df, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("tect_hutt_enfa_spec_asexual.png",
plot = tect_hutt_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
#sexual
tect_hutt_enfa_spec_sexual <- enfa_hex_plot(tect_hutt_sexual_df, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("tect_hutt_enfa_spec_sexual.png",
plot = tect_hutt_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
#asexual
hist(tect_hutt_asexual_enfa)
title(main = "Asexual", adj = 0.7, line = -12)
quartz_off_screen
2

quartz_off_screen
2


Trying out a repeat of the analyses with reduced environmental space. Prioritizing variables that will limit their distribution (i.e. variables that represent the extremes). After correlation analysis, we’re left with BIO4, BIO8, BIO11, BIO15, BIO17
| bio1 |
bio9 |
0.7683085 |
| bio1 |
bio5 |
0.9431235 |
| bio10 |
bio9 |
0.7649972 |
| bio10 |
bio5 |
0.9696441 |
| bio10 |
bio1 |
0.9949074 |
| bio11 |
bio9 |
0.7840988 |
| bio11 |
bio5 |
0.9097998 |
| bio11 |
bio1 |
0.9941228 |
| bio11 |
bio10 |
0.9798860 |
| bio6 |
bio9 |
0.7634527 |
| bio6 |
bio5 |
0.8549377 |
| bio6 |
bio1 |
0.9774484 |
| bio6 |
bio10 |
0.9527160 |
| bio6 |
bio11 |
0.9924265 |
| bio12 |
bio19 |
0.9303682 |
| bio13 |
bio19 |
0.9494262 |
| bio13 |
bio12 |
0.9904545 |
| bio16 |
bio19 |
0.9503474 |
| bio16 |
bio12 |
0.9911887 |
| bio16 |
bio13 |
0.9993100 |
| bio18 |
bio19 |
0.8488702 |
| bio18 |
bio12 |
0.9765329 |
| bio18 |
bio13 |
0.9544060 |
| bio18 |
bio16 |
0.9557642 |
| bio14 |
bio19 |
0.8939441 |
| bio14 |
bio12 |
0.9862519 |
| bio14 |
bio13 |
0.9664429 |
| bio14 |
bio16 |
0.9680861 |
| bio14 |
bio18 |
0.9878180 |
| bio17 |
bio19 |
0.8861880 |
| bio17 |
bio12 |
0.9881415 |
| bio17 |
bio13 |
0.9676936 |
| bio17 |
bio16 |
0.9693849 |
| bio17 |
bio18 |
0.9875497 |
| bio17 |
bio14 |
0.9958281 |
| bio4 |
bio6 |
-0.8042062 |
| bio2 |
bio3 |
0.9469371 |
| bio2 |
bio4 |
0.8977292 |
| bio7 |
bio3 |
0.8829596 |
| bio7 |
bio4 |
0.9549837 |
| bio7 |
bio2 |
0.9835939 |

Repeat the analysis with the reduced data set.
w_tect_hutt <- raster::subset(w, c("bio4", "bio8", "bio11", "bio15", "bio17"))
#get background env't for the species
tect_hutt_bg_env_subset <- bg_env_crop(tect_loc,
species = "huttoni",
environment = w_tect_hutt,
buffer = 0.5)
#enfa for the sexual species
tect_hutt_sexual_enfa_subset <- enfa_calc_fun(locs = tect_loc,
species = "huttoni",
reproductive_mode = "sexual",
mask_raster = tect_hutt_bg_env_subset)
#enfa for the asexual species
tect_hutt_asexual_enfa_subset <- enfa_calc_fun(locs = tect_loc,
species = "huttoni",
reproductive_mode = "asexual",
mask_raster = tect_hutt_bg_env_subset)
# write marginality scores to csv
readr::write_csv(
tect_hutt_asexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "tect_hutt_subset_asexual_marginality_score.csv")
)
readr::write_csv(
tect_hutt_sexual_enfa_subset$m %>% enframe(name = NULL, value = "marginality"),
file.path(spread_path, "tect_hutt_subset_sexual_marginality_score.csv")
)
# plot the marginality scores
tect_hutt_subset_marginality <-
marginality_lollipop(
sex_marg = tect_hutt_sexual_enfa_subset$m,
asex_marg = tect_hutt_asexual_enfa_subset$m,
full_species_name = "Tectarchus huttoni"
)
tect_hutt_subset_marginality
ggsave("tect_hutt_subset_marginality.png",
plot = tect_hutt_subset_marginality,
device = "png",
path = plot_path,
dpi = "retina")

Visualize with the reduced data set.
### 1) ENFA scatterplot
# access the relevant values for plotting
tect_hutt_asexual_df_subset <- tect_hutt_asexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = tect_hutt_asexual_enfa_subset$pr)
readr::write_csv(
tect_hutt_asexual_df_subset,
file.path(spread_path, "tect_hutt_asexual_df_subset.csv")
)
tect_hutt_sexual_df_subset <- tect_hutt_sexual_enfa_subset$li %>%
as_tibble() %>%
bind_cols(pr = tect_hutt_sexual_enfa_subset$pr)
readr::write_csv(
tect_hutt_sexual_df_subset,
file.path(spread_path, "tect_hutt_sexual_df_subset.csv")
)
# asexual
tect_hutt_subset_enfa_spec_asexual <- enfa_hex_plot(tect_hutt_asexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Asexual")
ggsave("tect_hutt_subset_enfa_spec_asexual.png",
plot = tect_hutt_subset_enfa_spec_asexual,
device = "png",
path = plot_path,
dpi = "retina")
# sexual
tect_hutt_subset_enfa_spec_sexual <- enfa_hex_plot(tect_hutt_sexual_df_subset, marg = Mar, spec = Spe1, repro_mode = "Sexual")
ggsave("tect_hutt_subset_enfa_spec_sexual.png",
plot = tect_hutt_subset_enfa_spec_sexual,
device = "png",
path = plot_path,
dpi = "retina")
### 2) ENFA histogram
# asexual
hist(tect_hutt_asexual_enfa_subset)
title(main = "Asexual", adj = 0.7, line = -12)
quartz_off_screen
2

quartz_off_screen
2


We’re also interested in seeing if asexual populations live in more unstable climatic areas relative to sexual populations.
tect_hutt_locs_asexual <- tect_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "asexual",
species == "huttoni",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
tect_hutt_locs_sexual <- tect_loc %>%
mutate(lat_long = str_c(latitude, longitude, sep = "_")) %>%
filter(reproductive_mode == "sexual",
species == "huttoni",
!duplicated(lat_long)) %>%
dplyr::select(longitude, latitude)
precip_asexual_tect_hutt <- raster::extract(precip_stability_scaled, tect_hutt_locs_asexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
precip_sexual_tect_hutt <- raster::extract(precip_stability_scaled, tect_hutt_locs_sexual) %>%
enframe(name = NULL, value = "precip_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
precip_df_tect_hutt <- bind_rows(precip_asexual_tect_hutt, precip_sexual_tect_hutt)
readr::write_csv(precip_df_tect_hutt,
file.path(spread_path, "tect_hutt_precip_stability_df.csv"))
tect_hutt_precip_stability_plot <- ggplot(data = precip_df_tect_hutt, aes(x = reproductive_mode, y = precip_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
tect_hutt_precip_stability_plot
ggsave("tect_hutt_precip_stability.png",
plot = tect_hutt_precip_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")

temp_asexual_tect_hutt <- raster::extract(temp_stability_scaled, tect_hutt_locs_asexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
temp_sexual_tect_hutt <- raster::extract(temp_stability_scaled, tect_hutt_locs_sexual) %>%
enframe(name = NULL, value = "temp_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
temp_df_tect_hutt <- bind_rows(temp_asexual_tect_hutt, temp_sexual_tect_hutt)
readr::write_csv(temp_df_tect_hutt,
file.path(spread_path, "tect_hutt_temp_stability_df.csv"))
tect_hutt_temp_stability_plot <- ggplot(data = temp_df_tect_hutt, aes(x = reproductive_mode, y = temp_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
tect_hutt_temp_stability_plot
ggsave("tect_hutt_precip_stability.png",
plot = tect_hutt_temp_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")

overall_asexual_tect_hutt <- raster::extract(overall_stability_scaled, tect_hutt_locs_asexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "asexual")
overall_sexual_tect_hutt <- raster::extract(overall_stability_scaled, tect_hutt_locs_sexual) %>%
enframe(name = NULL, value = "overall_stability_scaled") %>%
mutate(reproductive_mode = "sexual")
overall_df_tect_hutt <- bind_rows(overall_asexual_tect_hutt, overall_sexual_tect_hutt)
readr::write_csv(overall_df_tect_hutt,
file.path(spread_path, "tect_hutt_overall_stability_df.csv"))
tect_hutt_overall_stability_plot <- ggplot(data = overall_df_tect_hutt, aes(x = reproductive_mode, y = overall_stability_scaled, color = reproductive_mode)) +
geom_boxplot(width = 0.5, color = "black", fill = "transparent") +
geom_jitter(width = 0.2, alpha = 0.6) +
scale_color_viridis_d(option = "magma") +
theme_dark()
tect_hutt_overall_stability_plot
ggsave("tect_hutt_overall_stability.png",
plot = tect_hutt_overall_stability_plot,
device = "png",
path = plot_path,
dpi = "retina")

Put all output into species-specific subfolders.
tect_hutt_out_int_path <- file.path(interactive_path, "tectarchus_huttoni")
tect_hutt_out_plot_path <- file.path(plot_path, "tectarchus_huttoni")
tect_hutt_out_spread_path <- file.path(spread_path, "tectarchus_huttoni")
tect_hutt_out_obj_path <- file.path(obj_path, "tectarchus_huttoni")
# move interactive
move_to_species(in_path = interactive_path,
out_path = tect_hutt_out_int_path,
pattern = "tect_hutt")
# move plots
move_to_species(in_path = plot_path,
out_path = tect_hutt_out_plot_path,
pattern = "tect_hutt")
# move spreadsheets
move_to_species(in_path = spread_path,
out_path = tect_hutt_out_spread_path,
pattern = "tect_hutt")
# move objects
move_to_species(in_path = obj_path,
out_path = tect_hutt_out_obj_path,
pattern = "tect_hutt")
Tepakiphasma
Nothing. Only one locality.
Convenience scripts
These scripts aren’t crucial for reproducing this analysis, but were helpful for various reasons. Some of these have hard-coded paths and such, so no guarantees for use right out of the box.
This was a script I used to take full chelsa files, crop them to New Zealand extent, and write them to a file with my personal computer. I don’t have much memory, so unzipping to a temporary directory, then deleting the directory to free up space for the large files worked.
## get chelsa data
chelsa_folder <- "/Users/connorfrench/Dropbox/Old_Mac/climate-data/chelsa_30s_bio"
zip_files <- list.files(chelsa_folder, full.names = TRUE)
# using the Unarchiver commandline tools for Mac to unzip the 7zip chelsa layers. Regular unzip() does not work with 7z zipped files
for (file in zip_files) {
# set temp directory
tempd <- tempdir()
system(paste("unar", file, "-o", tempd))
r <- raster(list.files(tempd, pattern = "*.tif", full.names = TRUE)) %>%
crop(extent(166, 179, -48, -34))
writeRaster(r, filename = paste0("~/Desktop/", list.files(tempd, pattern = "*.tif")), format = "GTiff")
unlink(tempd, recursive = TRUE)
}
LS0tCnRpdGxlOiAiU3RpY2sgSW5zZWN0IENsaW1hdGUgUENBIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0aGVtZTogZmxhdGx5CiAgICBoaWdobGlnaHQ6IHRhbmdvCi0tLQoKU29ycnkgZm9yIGFsbCBvZiB0aGUgcGFja2FnZXMuIFRoZXkgZ3JldyBhbmQgZ3JldyBhbmQgZ3JldywgYW5kIEkgZG9uJ3Qgd2FudCB0byByZWZhY3RvciBldmVyeXRoaW5nIHRvIHJlZHVjZSB0aGUgZGVwZW5kZW5jaWVzLgoKYGBge3IgbWVzc2FnZT1GQUxTRX0KbGlicmFyeShyYXN0ZXIpCmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShzZikKI1JTdG9vbGJveCBoYXMgc29tZSBkZXBlbmRlbmNpZXMgbGlrZSBvcGVuTVAgdGhhdCBjYW4gYmUgZGlmZmljdWx0IHRvIGNvbXBpbGUgb24gYSBNYWMgKG5lZWRlZCBmb3IgdGhlIGRlcGVuZGVudCBwYWNrYWdlICJjYXJldCIpLiBJZiB5b3UgaGF2ZSBIaWdoIFNpZXJyYSBPUyBvciBuZXdlciwgc2VhcmNoIGZvciBpbnN0cnVjdGlvbnMgc3BlY2lmaWMgdG8geW91ciBPUy0gaXQncyBhIGxvdCBlYXNpZXIgdGhhbiBvbGRlciBPUydzLgpsaWJyYXJ5KFJTdG9vbGJveCkKbGlicmFyeShsZWFmbGV0KQpsaWJyYXJ5KHBsb3RseSkKbGlicmFyeShnZGF0YSkKbGlicmFyeShCU0RBKQpsaWJyYXJ5KGFkZTQpCmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KGphbml0b3IpCmxpYnJhcnkocm5hdHVyYWxlYXJ0aCkKbGlicmFyeShhZGVoYWJpdGF0SFMpCmxpYnJhcnkoY2xpbWF0ZVN0YWJpbGl0eSkKbGlicmFyeShodG1sd2lkZ2V0cykKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2dzcGF0aWFsKQpsaWJyYXJ5KGhlcmUpCmxpYnJhcnkobWFwdmlldykKbGlicmFyeShmcykKCnJfcGF0aCA8LSBoZXJlOjpoZXJlKCJSIikKc291cmNlKGZpbGUucGF0aChyX3BhdGgsICJwbG90X2xlYWZsZXRfZnVuY3Rpb24uUiIpKSAjc291cmNlIGxvY2FsaXR5IHBsb3R0aW5nIGZ1bmN0aW9uCnNvdXJjZShmaWxlLnBhdGgocl9wYXRoLCAicGxvdF9jbGltYXRlX3BjYV9mdW5jdGlvbi5SIikpICNzb3VyY2UgcGNhIHBsb3R0aW5nIGZ1bmN0aW9uCnNvdXJjZShmaWxlLnBhdGgocl9wYXRoLCAic3BlY2llc19wY2FfZnVuY3Rpb24uUiIpKSAjc291cmNlIGZ1bmN0aW9uIHRoYXQgY29tcHV0ZXMgY2xpbWF0ZSBwY2EgcGVyIHNwZWNpZXMKc291cmNlKGZpbGUucGF0aChyX3BhdGgsICJtaW5fY29udmV4X3BvbHkuUiIpKSAjc291cmNlIGZ1bmN0aW9uIHRoYXQgY3JlYXRlcyBhIG1pbmltdW0gY29udmV4IHBvbHlnb24gYXJvdW5kIHBvaW50cwpzb3VyY2UoZmlsZS5wYXRoKHJfcGF0aCwgImVuZmFfY2FsY19mdW5jdGlvbi5SIikpCnNvdXJjZShmaWxlLnBhdGgocl9wYXRoLCAibWFyZ2luYWxpdHlfbG9sbGlwb3BfcGxvdC5SIikpCnNvdXJjZShmaWxlLnBhdGgocl9wYXRoLCAicHJlc2VuY2VfYWJzZW5jZV9yYXN0ZXJfZnVuY3Rpb24uUiIpKQpzb3VyY2UoZmlsZS5wYXRoKHJfcGF0aCwgImNyb3BfYmFja2dyb3VuZF9lbnZfZnVuY3Rpb24uUiIpKQpzb3VyY2UoZmlsZS5wYXRoKHJfcGF0aCwgImVuZmFfaGV4X3Bsb3QuUiIpKQpzb3VyY2UoZmlsZS5wYXRoKHJfcGF0aCwgInRvdGFsX2NsaW1hdGVfcGNhX3Bsb3QuUiIpKQpzb3VyY2UoZmlsZS5wYXRoKHJfcGF0aCwgInJhc3Rlcl9jb3JyZWxhdGlvbl9mdW5jdGlvbi5SIikpCnNvdXJjZShmaWxlLnBhdGgocl9wYXRoLCAibW92ZV90b19zcGVjaWVzLlIiKSkKYGBgCgpDcmVhdGUgc3ViZGlyZWN0b3JpZXMgKGlmIG5lZWRlZCkgYW5kIGVzdGFibGlzaCBwYXRocy4KYGBge3J9CiMgZnVuY3Rpb24gdG8gY2hlY2sgaWYgc3ViZm9sZGVyIGV4aXN0cy4gSWYgbm90LCBtYWtlIGl0CmNyZWF0ZV9kaXIgPC0gZnVuY3Rpb24ob3V0X3BhdGgpIHsKICBpZiAoIWRpci5leGlzdHMob3V0X3BhdGgpKSB7CiAgICBkaXIuY3JlYXRlKG91dF9wYXRoKQogIH0gZWxzZQogICAgcHJpbnQoIkRpcmVjdG9yeSBhbHJlYWR5IHRoZXJlLiIpCn0KCiMgcGF0aCBmb3IgaW50ZXJhY3RpdmUgcGxvdHMsIG1hcHMsIGV0Yy4gb3V0cHV0CmludGVyYWN0aXZlX3BhdGggPC0gaGVyZTo6aGVyZSgib3V0cHV0IiwgImludGVyYWN0aXZlX3Bsb3RzIikKCmNyZWF0ZV9kaXIocHJlY2lwX3BhdGgpCgojIHRlbXBlcmF0dXJlIGNsaW1hdGUgZGF0YQp0ZW1wX3BhdGggPC0KICBoZXJlOjpoZXJlKCJkYXRhIiwKICAgICAgICJjbGltYXRlIiwKICAgICAgICJwYWxlb2NsaW1fbGF0ZV9wbGVpc3RvY2VuZSIsCiAgICAgICAidGVtcGVyYXR1cmUiKQoKY3JlYXRlX2Rpcih0ZW1wX3BhdGgpCgojIHByZWNpcGl0YXRpb24gY2xpbWF0ZSBkYXRhCnByZWNpcF9wYXRoIDwtCiAgaGVyZTo6aGVyZSgiZGF0YSIsCiAgICAgICAiY2xpbWF0ZSIsCiAgICAgICAicGFsZW9jbGltX2xhdGVfcGxlaXN0b2NlbmUiLAogICAgICAgInByZWNpcGl0YXRpb24iKQoKY3JlYXRlX2RpcihwcmVjaXBfcGF0aCkKCiMgcmFzdGVyIG91dHB1dApyYXN0ZXJfcGF0aCA8LSAKICBoZXJlOjpoZXJlKCJvdXRwdXQiLAogICAgICAgICAgICAgInJhc3RlcnMiKQoKY3JlYXRlX2RpcihyYXN0ZXJfcGF0aCkKCiMgbWFwIChub24taW50ZXJhY3RpdmUpIG91dHB1dAptYXBfcGF0aCA8LSBoZXJlOjpoZXJlKCJvdXRwdXQiLCAibWFwcyIpCgpjcmVhdGVfZGlyKG1hcF9wYXRoKQoKIyBwbG90IChub24taW50ZXJhY3RpdmUpIG91dHB1dApwbG90X3BhdGggPC0gaGVyZTo6aGVyZSgib3V0cHV0IiwgInBsb3RzIikKCmNyZWF0ZV9kaXIocGxvdF9wYXRoKQoKIyBzcHJlYWRzaGVldCBvdXRwdXQKc3ByZWFkX3BhdGggPC0gaGVyZTo6aGVyZSgib3V0cHV0IiwgInNwcmVhZHNoZWV0cyIpCgpjcmVhdGVfZGlyKHNwcmVhZF9wYXRoKQoKIyBSIG9iamVjdCAoZS5nLiAuUkRTIGZpbGVzKSBvdXRwdXQKb2JqX3BhdGggPC0gaGVyZTo6aGVyZSgib3V0cHV0IiwgIm9iamVjdHMiKQoKY3JlYXRlX2RpcihvYmpfcGF0aCkKCmBgYAoKCgpSZWFkIGluIHRoZSBzcHJlYWRzaGVldCBhbmQgdGFrZSBhIGxvb2sgYXQgdGhlIGRhdGEuCgpgYGB7cn0KIyBkYXRhIHBhdGgKbG9jX3BhdGggPC0gaGVyZTo6aGVyZSgiZGF0YSIsICJhbGwgc3BlY2llcyBOZXdfNi0xNC0xOS54bHN4IikKCiMjIyByZWFkIGluIHNwcmVhZHNoZWV0CmxvYyA8LSByZWFkX3hsc3gobG9jX3BhdGgpICU+JQogIGphbml0b3I6OmNsZWFuX25hbWVzKCkgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9IGFzLmZhY3RvcihyZXByb2R1Y3RpdmVfbW9kZSkpIAoKI2dldCB0aGUgbnVtYmVyIG9mIGluZGl2aWR1YWxzLCBhbmQgdGhlIHNleHVhbGl0eSBjb3VudHMgcGVyIHNwZWNpZXMKY291bnRfcmVwcm9fbW9kZSA8LSBsb2MgJT4lIAogIGdyb3VwX2J5KGdlbnVzLCBzcGVjaWVzLCByZXByb2R1Y3RpdmVfbW9kZSkgJT4lIAogIGRwbHlyOjpjb3VudCgpICU+JSAKICBtdXRhdGUoZ2VudXNfc3BlY2llcyA9IHN0cl9jKGdlbnVzLCBzcGVjaWVzLCBzZXAgPSAiXyIpLAogICAgICAgICBnZW51c19zcGVjaWVzID0gc3RyX3JlcGxhY2VfYWxsKGdlbnVzX3NwZWNpZXMsICIgIiwgIl8iKSwKICAgICAgICAgZ2VudXNfc3BlY2llcyA9IHN0cl9yZXBsYWNlX2FsbChnZW51c19zcGVjaWVzLCAiXFwuIiwgIiIpKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBtdXRhdGUoZ2VudXNfc3BlY2llcyA9IGZjdF9yZW9yZGVyKGdlbnVzX3NwZWNpZXMsIG4sIHN1bSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBnZW51c19zcGVjaWVzLCB5ID0gbiwgZmlsbCA9IHJlcHJvZHVjdGl2ZV9tb2RlKSkgKwogIGdlb21fY29sKCkgKwogIGNvb3JkX2ZsaXAoKSArIAogIHRoZW1lX21pbmltYWwoKQoKY291bnRfcmVwcm9fbW9kZQpgYGAKCiMjIE1hcApQbG90IGEgbGVhZmxldCBtYXAgb2YgdGhlIGxvY2FsaXRpZXMuIFRoZSBsZWFmbGV0IG1hcCBpcyBpbnRlcmFjdGl2ZS4gWW91IGNhbiBjbGljayBvbiB0aGUgbG9jYWxpdGllcyBhbmQgYSBmbGFnIHdpdGggc29tZSBtZXRhZGF0YSB3aWxsIHBvcCB1cCEgCgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojbWFrZSBsb2NhbGl0eSBzaGFwZSBmaWxlIGFuZCBhc3NpZ24gV0dTIGNvb3JkIHN5c3RlbQpjb29yZF9wb2ludHMgPC0gc3RfYXNfc2YobG9jLCBjb29yZHMgPSBjKCJsb25naXR1ZGUiLCAibGF0aXR1ZGUiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBjcnMgPSA0MzI2LCBhZ3IgPSAiY29uc3RhbnQiKQoKI3VzZSBzb3VyY2VkIHBsb3RfbG9jc19sZWFmbGV0IHNjcmlwdCB0byBwbG90IGxvY2FsaXRpZXMKYWxsX3Bsb3QgPC0gcGxvdF9sb2NzX2xlYWZsZXQobG9jLCAicmVwcm9kdWN0aXZlX21vZGUiKQoKYWxsX3Bsb3QKCiMgc2F2ZSB0aGUgbWFwCm1hcHZpZXc6Om1hcHNob3QoCiAgYWxsX3Bsb3QsCiAgdXJsID0gZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJhbGxfc3BlY2llc19tYXAuaHRtbCIpLAogIGZpbGUgPSBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgImFsbF9zcGVjaWVzX21hcC5wZGYiKQopCmBgYAoKIyMgUENBLUdlbmVyYSB7LnRhYnNldH0KCiMjIyBDbGltYXRlIERhdGEKUmVhZCBpbiB0aGUgYmlvY2xpbSBsYXllcnMgZm9yIGFuYWx5c2lzLiBJJ20gdXNpbmcgYWxsIDE5IGZvciB0aGlzIHByZWxpbWluYXJ5IGV4cGxvcmF0aW9uLiBJJ20gdXNpbmcgQ0hFTFNBIHYxLjIgZGF0YSBkb3dubG9hZGVkIGZyb20gW3RoZWlyIHdlYnNpdGVdKGh0dHA6Ly9jaGVsc2EtY2xpbWF0ZS5vcmcvZG93bmxvYWRzLykuIFBsb3R0aW5nIHRoZSBmaXJzdCB0ZW1wZXJhdHVyZSBsYXllciB0byB0YWtlIGEgbG9vayBhdCB0aGUgZGF0YS4KYGBge3IgY2FjaGU9VFJVRX0KY2xpbV9maWxlcyA8LSBoZXJlOjpoZXJlKCJkYXRhIiwgImNsaW1hdGUiKSAlPiUgCiAgbGlzdC5maWxlcyhwYXR0ZXJuID0gIi50aWYiLCBmdWxsLm5hbWVzID0gVFJVRSkKCncgPC0gc3RhY2soY2xpbV9maWxlcykKCiNzaG9ydGVuIHRoZSBuYW1lcyBvZiB0aGUgYmlvY2xpbXMKbmFtZXModykgPC0gcGFzdGUwKAogIHN0cmluZ3I6OnN0cl9leHRyYWN0KG5hbWVzKHcpLCAiYmlvIiksIAogIHN0cmluZ3I6OnN0cl9leHRyYWN0KG5hbWVzKHcpLCAiXFxkKyQiKQogICkKCgpnZ3Bsb3QoKSArCiAgZ2dzcGF0aWFsOjpsYXllcl9zcGF0aWFsKGRhdGEgPSB3W1sxXV0pICsKICBzY2FsZV9maWxsX3ZpcmlkaXNfYyhuYS52YWx1ZSA9ICJ0cmFuc3BhcmVudCIpICsKICBsYWJzKGZpbGwgPSAiQW5udWFsIEF2ZyBUZW1wIChDKjEwKSIpICsKICB0aGVtZV9taW5pbWFsKCkKICAKYGBgCgoKIyMjIFBDQSBieSBsb2NhbGl0eQpUaGlzIGlzIGEgUENBIG9mIHRoZSBjbGltYXRlIGRhdGEgZXh0cmFjdGVkIGZvciBlYWNoIGxvY2FsaXR5LCByYXRoZXIgdGhhbiBhIFBDQSBvZiB0aGUgdG90YWwgY2xpbWF0ZSBzcGFjZS4gVGhpcyBnaXZlcyB1cyBhIGdlbmVyYWwgaWRlYSBvZiBkaWZmZXJlbmNlcyBpbiBlbnZpcm9ubWVudGFsIG5pY2hlLgoKUnVuIHRoZSBwY2EgYW5kIGNoZWNrIG91dCB2YXJpYWJsZSBsb2FkaW5ncyBhbmQgcHJvcG9ydGlvbiBvZiB2YXJpYW5jZSBleHBsYWluZWQgYnkgY29tcG9uZW50cy4KCmBgYHtyIGNhY2hlPVRSVUV9CiNleHRyYWN0IGRhdGEgZnJvbSBjaGVsc2EgZm9yIGVhY2ggbG9jYWxpdHkuIE1ha2luZyB0aGlzIGludG8gYSBkYXRhIGZyYW1lIHdpdGggY29sdW1ucyBsYWJlbGVkIHNvIHRoZSByb3cgbGFiZWxpbmcgbGluZXMgdXAgYWZ0ZXIgSSByZW1vdmUgdGhlIE5Bcy4KI2V4dHJhY3QgZGF0YSBmcm9tIHdvcmxkY2xpbSBmb3IgZWFjaCBsb2NhbGl0eS4KY29vcmRzIDwtIGRhdGEuZnJhbWUobGF0aXR1ZGUgPSBsb2MkbG9uZ2l0dWRlLCBsb25naXR1ZGUgPSBsb2MkbGF0aXR1ZGUpCgpsb2NfY2xpbSA8LSBkcGx5cjo6YmluZF9jb2xzKGxvYywgcmFzdGVyOjpleHRyYWN0KHcsIGNvb3JkcywgbWV0aG9kID0gInNpbXBsZSIsIGRmID0gVFJVRSkpICU+JSAKICBkcm9wX25hKGJpbzEpICU+JSAKICBkcGx5cjo6c2VsZWN0KC1JRCkKCiNtYWtlIGEgbWF0cml4IG9mIG9ubHkgYmlvY2xpbSB2YWx1ZXMKY2xpbV9tYXQgPC0gbG9jX2NsaW1bLGdyZXAoImJpbyIsIG5hbWVzKGxvY19jbGltKSldICU+JSBhcy5tYXRyaXgoKQoKI3J1biBwY2Egb24gY2xpbWF0ZSB2YXJpYWJsZXMKY2xpbV9wY2EgPC0gcHJjb21wKGNsaW1fbWF0LCBzY2FsZSA9IFRSVUUpCnN1bW1hcnlfcGNhIDwtIHN1bW1hcnkoY2xpbV9wY2EpICNjaGVjayBvdXQgdGhlIGNvbXBvbmVudHMKCiNwbG90IHRhYmxlcwpzdW1tYXJ5X3BjYQprbml0cjo6a2FibGUocm91bmQoY2xpbV9wY2Ekcm90YXRpb25bLDE6M10sMykpICNUYWJsZSBvZiBsb2FkaW5nIHNjb3JlcyBmb3IgdGhlIGZpcnN0IDMgUENzLgoKYGBgCgpUd28gcGxvdHM6IE9uZSBwbG90IG9mIHRoZSBQQ0EgY29sb3JlZCBhY2NvcmRpbmcgdG8gZ2VudXMsIHdpdGggY29udmV4IGh1bGxzIHN1cnJvdW5kaW5nIHRoZSBnZW5lcmEuIEl0IGxvb2tzIGxpa2UgdGhpcyByZWZsZWN0cyBhIGxhdGl0dWRpbmFsIGdyYWRpZW50IGluIHRlbXBlcmF0dXJlISBZb3UgY2FuIGludGVyYWN0IHdpdGggdGhlIFBDQSBwbG90IGJ5IGNsaWNraW5nIG9uIHBvaW50cyB0byB2aWV3IGFzc29jaWF0ZWQgbWV0YWRhdGEuIFlvdSBjYW4gaXNvbGF0ZSB0aGUgZ2VudXMgeW91IHdhbnQgdG8gdmlldyBieSBkb3VibGUgY2xpY2tpbmcgdGhlIGdlbnVzIGluIHRoZSBsZWdlbmQhIFlvdSBjYW4gYWxzbyByZW1vdmUgYSBnZW51cyBieSBjbGlja2luZyBvbiBpdCBvbmNlLiBUaGVyZSdzIHNvbWUgb3RoZXIgZnVuY3Rpb25hbGl0eSB5b3UgY2FuIGV4cGxvcmUgaW4gdGhlIHRvb2xiYXIgYXQgdGhlIHRvcCBvZiB0aGUgcGxvdC4gVGhlIHNlY29uZCBwbG90IGlzIGEgUENBIGNvbG9yZWQgYWNjb3JkaW5nIHRvIHJlcHJvZHVjdGl2ZSBtb2RlLiBJdCBsb29rcyBsaWtlIGFzZXh1YWwgcG9wdWxhdGlvbnMgb2NjdXB5IHNsaWdodGx5IGxhcmdlciBuaWNoZSBzcGFjZSwgYnV0IGJvdGggcmVwcm9kdWN0aXZlIG1vZGVzIGhhdmUgYSBzaW1pbGFyIG5pY2hlIGNlbnRlci4KYGBge3Igd2FybmluZz1GQUxTRX0KI2FkZCBwY2EgcmVzdWx0cyB0byBsb2NfY2xpbSBkYXRhIGZyYW1lCmxvY19jbGltIDwtIGRhdGEuZnJhbWUobG9jX2NsaW0sIGNsaW1fcGNhJHgpCgojdXNlIHNvdXJjZWQgcGxvdF9jbGltX3BjYSBmdW5jdGlvbiB0byBwbG90IHRoZSBwY2EgcmVzdWx0cy4gYXJncyBhcmUgdGhlIGRhdGEgc2V0IHdpdGggc3BlY2llcyBuYW1lcyBhbmQgUEMgYXhpcyB2YWx1ZXMgYW5kIHRoZSBwY2Egc3VtbWFyeQphbGxfcGNhIDwtIHBsb3RfY2xpbV9wY2EobG9jX2NsaW0sIHN1bW1hcnlfcGNhLCBmYWN0b3IgPSAiZ2VudXMiKQphbGxfcGNhCgojdXNlIHNvdXJjZWQgcGxvdF9jbGltX3BjYSBmdW5jdGlvbiB0byBwbG90IHRoZSBwY2EgcmVzdWx0cy4gYXJncyBhcmUgdGhlIGRhdGEgc2V0IHdpdGggc3BlY2llcyBuYW1lcyBhbmQgUEMgYXhpcyB2YWx1ZXMgYW5kIHRoZSBwY2Egc3VtbWFyeQpyZXByb19wY2EgPC0KICBwbG90X2NsaW1fcGNhKGxvY19jbGltLCBzdW1tYXJ5X3BjYSwgZmFjdG9yID0gInJlcHJvZHVjdGl2ZV9tb2RlIikKcmVwcm9fcGNhCgoKIyBzYXZlIHRoZSBwbG90IGNvbG9yZWQgYnkgZ2VudXMKaHRtbHdpZGdldHM6OnNhdmVXaWRnZXQoCiAgYWxsX3BjYSwKICBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgImFsbF9zcGVjaWVzX3BjYV9nZW51cy5odG1sIiksCiAgc2VsZmNvbnRhaW5lZCA9IFRSVUUKKQoKIyBzYXZlIHRoZSBwbG90IGNvbG9yZWQgYnkgcmVwcm9kdWN0aXZlIG1vZGUKaHRtbHdpZGdldHM6OnNhdmVXaWRnZXQoCiAgcmVwcm9fcGNhLAogIGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCAiYWxsX3NwZWNpZXNfcGNhX3JlcHJvLmh0bWwiKSwKICBzZWxmY29udGFpbmVkID0gVFJVRQopCgpgYGAKCkV4YW1pbmluZyB3aGV0aGVyIGFzZXh1YWwgcG9wdWxhdGlvbnMgb2NjdXB5IG1vcmUgdW5zdGFibGUgY2xpbWF0ZXMgdGhhbiBzZXh1YWwgcG9wdWxhdGlvbnMuIE9ubHkgdXNpbmcgc3BlY2llcyB3aXRoIG11bHRpcGxlIHNleHVhbCBhbmQgYXNleHVhbCBwb3B1bGF0aW9ucy4gQXNleHVhbCBwb3BzIHRlbmQgdG8gb2NjdXB5IG1vcmUgc3RhYmxlIHRlbXBlcmF0dXJlIGVudmlyb25tZW50cywgYnV0IGxlc3Mgc3RhYmxlIHByZWNpcGl0YXRpb24gZW52aXJvbm1lbnRzLiBXZSdyZSBlc3RpbWF0aW5nIHN0YWJpbGl0eSB1c2luZyB0aGUgbWV0aG9kIHByZXNlbnRlZCBieSBPd2VucyBhbmQgR3VyYWxuaWNrIDIwMTktIGNsaW1hdGVTdGFiaWxpdHk6IEFOIFIgUEFDS0FHRSBUTyBFU1RJTUFURSBDTElNQVRFIFNUQUJJTElUWSBGUk9NIFRJTUUtU0xJQ0UgQ0xJTUFUT0xPR0lFUy4KCmBgYHtyIGNhY2hlPVRSVUUsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMjIyBDcmVhdGluZyB0ZW1wZXJhdHVyZSBhbmQgcHJlY2lwaXRhdGlvbiBzdGFiaWxpdHkgbGF5ZXJzCiMjIyBVc2luZyBiaW8xIChhdmVyYWdlIHRlbXApIGFuZCBiaW8xMiAoYXZlcmFnZSBwcmVjaXApCiMjIyAyLjUgYXJjbWluIHJlc29sdXRpb24sIGFscmVhZHkgY3JvcHBlZCB0byBOWiB0byBzcGVlZCB1cCBjb21wdXRhdGlvbiB0aW1lCgoKI3RpbWUgc2xpY2VzIGFyZSBjYWxjdWxhdGVkIGFzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIG1pZHBvaW50cyBvZiB0aGUgdHdvIHRpbWUgcGVyaW9kcyB0aGUgY2xpbWF0ZSBsYXllcnMgd2VyZSBjYWxjdWxhdGVkIGZvciAoZS5nLiBtaWRwb2ludCBvZiBMSCA9ICg0LjIga2EgLSAwLjMga2EpIC8gMiArIDAuMyBrYSA9IDIuMjUsIG1pZHBvaW50IG9mIE1IID0gKDguMzI2IGthIC0gNC4yIGthKSAvIDIgKyA0LjIgPSA2LjI2My4gdGltZV9zbGljZSA9IDYuMjYzIC0gMi4yNSA9IDQuMDEzKQp0aW1lX3NsaWNlcyA8LSBjKDI1NTAsIDQwMTMsIDYwMzcsIDE1MDAsIDIwNTAsIDUxNTApCgoKcHJlY2lwX2RldmlhdGlvbiA8LQogIGNsaW1hdGVTdGFiaWxpdHk6OmRldmlhdGlvblRocm91Z2hUaW1lKHZhcmlhYmxlRGlyZWN0b3J5ID0gcHJlY2lwX3BhdGgsIHRpbWVTbGljZVBlcmlvZCA9IHRpbWVfc2xpY2VzKQoKcHJlY2lwX3N0YWJpbGl0eSA8LSAoMSAvIHByZWNpcF9kZXZpYXRpb24pCnByZWNpcF9zdGFiaWxpdHlfc2NhbGVkIDwtIGNsaW1hdGVTdGFiaWxpdHk6OnJlc2NhbGUwdG8xKHByZWNpcF9zdGFiaWxpdHkpCgojIHdyaXRlIHByZWNpcGl0YXRpb24gc3RhYmlsaXR5IHRvIGZpbGUKd3JpdGVSYXN0ZXIoCiAgcHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQsCiAgZmlsZW5hbWUgPSBmaWxlLnBhdGgocmFzdGVyX3BhdGgsICJwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZC50aWYiKSwKICBmb3JtYXQgPSAiR1RpZmYiCikKCgp0ZW1wX2RldmlhdGlvbiA8LQogIGNsaW1hdGVTdGFiaWxpdHk6OmRldmlhdGlvblRocm91Z2hUaW1lKHZhcmlhYmxlRGlyZWN0b3J5ID0gdGVtcF9wYXRoLCB0aW1lU2xpY2VQZXJpb2QgPSB0aW1lX3NsaWNlcykKCnRlbXBfc3RhYmlsaXR5IDwtICgxIC8gdGVtcF9kZXZpYXRpb24pCnRlbXBfc3RhYmlsaXR5X3NjYWxlZCA8LSBjbGltYXRlU3RhYmlsaXR5OjpyZXNjYWxlMHRvMSh0ZW1wX3N0YWJpbGl0eSkKCiMgd3JpdGUgdGVtcGVyYXR1cmUgc3RhYmlsaXR5IHRvIGZpbGUKd3JpdGVSYXN0ZXIoCiAgdGVtcF9zdGFiaWxpdHlfc2NhbGVkLAogIGZpbGVuYW1lID0gZmlsZS5wYXRoKHJhc3Rlcl9wYXRoLCAidGVtcF9zdGFiaWxpdHlfc2NhbGVkLnRpZiIpLAogIGZvcm1hdCA9ICJHVGlmZiIKKQoKb3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkIDwtIHByZWNpcF9zdGFiaWxpdHlfc2NhbGVkICogdGVtcF9zdGFiaWxpdHlfc2NhbGVkCgojIHdyaXRlIG92ZXJhbGwgc3RhYmlsaXR5IHRvIGZpbGUKd3JpdGVSYXN0ZXIoCiAgb3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkLAogIGZpbGVuYW1lID0gZmlsZS5wYXRoKHJhc3Rlcl9wYXRoLCAib3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkLnRpZiIpLAogIGZvcm1hdCA9ICJHVGlmZiIKKQoKdGVtcF9zdGFiaWxpdHlfbWFwIDwtIGdncGxvdCgpICsKICBnZ3NwYXRpYWw6OmxheWVyX3NwYXRpYWwoZGF0YSA9IHRlbXBfc3RhYmlsaXR5X3NjYWxlZCkgKwogIGxhYnModGl0bGUgPSAiVGVtcGVyYXR1cmUgc3RhYmlsaXR5IikgKwogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG5hLnZhbHVlID0gInRyYW5zcGFyZW50IikgKwogIHRoZW1lX21pbmltYWwoKQoKcHJlY2lwX3N0YWJpbGl0eV9tYXAgPC0gZ2dwbG90KCkgKwogIGdnc3BhdGlhbDo6bGF5ZXJfc3BhdGlhbChkYXRhID0gcHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQpICsKICBsYWJzKHRpdGxlID0gIlByZWNpcGl0YXRpb24gc3RhYmlsaXR5IikgKwogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG5hLnZhbHVlID0gInRyYW5zcGFyZW50IikgKwogIHRoZW1lX21pbmltYWwoKQoKb3ZlcmFsbF9zdGFiaWxpdHlfbWFwIDwtIGdncGxvdCgpICsKICBnZ3NwYXRpYWw6OmxheWVyX3NwYXRpYWwoZGF0YSA9IG92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCkgKwogIGxhYnModGl0bGUgPSAiT3ZlcmFsbCBzdGFiaWxpdHkiKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzX2MobmEudmFsdWUgPSAidHJhbnNwYXJlbnQiKSArCiAgdGhlbWVfbWluaW1hbCgpCgp0ZW1wX3N0YWJpbGl0eV9tYXAKcHJlY2lwX3N0YWJpbGl0eV9tYXAKb3ZlcmFsbF9zdGFiaWxpdHlfbWFwCgpnZ3NhdmUoInRlbXBfc3RhYmlsaXR5LnBuZyIsCiAgICAgICBwbG90ID0gdGVtcF9zdGFiaWxpdHlfbWFwLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gbWFwX3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCmdnc2F2ZSgicHJlY2lwX3N0YWJpbGl0eS5wbmciLAogICAgICAgcGxvdCA9IHByZWNpcF9zdGFiaWxpdHlfbWFwLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gbWFwX3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCmdnc2F2ZSgib3ZlcmFsbF9zdGFiaWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSBvdmVyYWxsX3N0YWJpbGl0eV9tYXAsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBtYXBfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKYGBgCgoKClBsb3Qgc3RhYmlsaXR5IGFjcm9zcyBzcGVjaWVzLgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCiMgZmlsdGVyIGZvciByZWxldmFudCBzcGVjaWVzIGFuZCBhc2V4dWFsIHJlcHJvZHVjdGl2ZSBtb2RlCmFzZXh1YWxfbG9jcyA8LSBsb2MgJT4lCiAgbXV0YXRlKGxhdF9sb25nID0gc3RyX2MobGF0aXR1ZGUsIGxvbmdpdHVkZSkpICU+JQogIGZpbHRlcigKICAgIHJlcHJvZHVjdGl2ZV9tb2RlID09ICJhc2V4dWFsIiwKICAgIHNwZWNpZXMgPT0gImhvcnJpZHVzIiB8CiAgICAgIHNwZWNpZXMgPT0gImp1Y3VuZHVtIiB8CiAgICAgIHNwZWNpZXMgPT0gImhvb2tlcmkiIHwKICAgICAgc3BlY2llcyA9PSAiYW5udWxhdGEiIHwKICAgICAgc3BlY2llcyA9PSAib3ZvYmVzc3VzIiB8CiAgICAgIHNwZWNpZXMgPT0gImh1dHRvbmkiLAogICAgIWR1cGxpY2F0ZWQobGF0X2xvbmcpCiAgKSAlPiUKICBkcGx5cjo6c2VsZWN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUpCgojIGZpbHRlciBmb3IgcmVsZXZhbnQgc3BlY2llcyBhbmQgc2V4dWFsIHJlcHJvZHVjdGl2ZSBtb2RlCnNleHVhbF9sb2NzIDwtIGxvYyAlPiUKICBtdXRhdGUobGF0X2xvbmcgPSBzdHJfYyhsYXRpdHVkZSwgbG9uZ2l0dWRlKSkgJT4lCiAgZmlsdGVyKAogICAgcmVwcm9kdWN0aXZlX21vZGUgPT0gInNleHVhbCIsCiAgICBzcGVjaWVzID09ICJob3JyaWR1cyIgfAogICAgICBzcGVjaWVzID09ICJqdWN1bmR1bSIgfAogICAgICBzcGVjaWVzID09ICJob29rZXJpIiB8CiAgICAgIHNwZWNpZXMgPT0gImFubnVsYXRhIiB8CiAgICAgIHNwZWNpZXMgPT0gIm92b2Jlc3N1cyIgfAogICAgICBzcGVjaWVzID09ICJodXR0b25pIiwKICAgICFkdXBsaWNhdGVkKGxhdF9sb25nKQogICkgJT4lCiAgZHBseXI6OnNlbGVjdChsb25naXR1ZGUsIGxhdGl0dWRlKQoKIyBleHRyYWN0IHByZWNpcHRpdGF0aW9uIHZhbHVlcyBhbmQgYmluZCBpbnRvIGEgbmV3IGRhdGFmcmFtZQpwcmVjaXBfYXNleHVhbCA8LQogIHJhc3Rlcjo6ZXh0cmFjdChwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCwgYXNleHVhbF9sb2NzKSAlPiUKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JQogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCnByZWNpcF9zZXh1YWwgPC0KICByYXN0ZXI6OmV4dHJhY3QocHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQsIHNleHVhbF9sb2NzKSAlPiUKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JQogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiKQoKcHJlY2lwX2RmIDwtIGJpbmRfcm93cyhwcmVjaXBfYXNleHVhbCwgcHJlY2lwX3NleHVhbCkKCiMgcGxvdCBwcmVjaXBpdGF0aW9uIHN0YWJpbGl0eQpwcmVjaXBfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KAogIGRhdGEgPSBwcmVjaXBfZGYsCiAgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IHByZWNpcF9zdGFiaWxpdHlfc2NhbGVkLCBmaWxsID0gcmVwcm9kdWN0aXZlX21vZGUpCikgKwogIGdlb21fdmlvbGluKHdpZHRoID0gMC44KSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC4xLAogICAgICAgICAgICAgICBjb2xvciA9ICJncmF5IiwKICAgICAgICAgICAgICAgZmlsbCA9ICJ0cmFuc3BhcmVudCIpICsKICBzY2FsZV9maWxsX3ZpcmlkaXNfZChvcHRpb24gPSAibWFnbWEiKSArCiAgdGhlbWVfZGFyaygpCgpwcmVjaXBfc3RhYmlsaXR5X3Bsb3QKCiMgZXh0cmFjdCB0ZW1wZXJhdHVyZSB2YWx1ZXMgYW5kIGJpbmQgaW50byBhIG5ldyBkYXRhIGZyYW1lCnRlbXBfYXNleHVhbCA8LQogIHJhc3Rlcjo6ZXh0cmFjdCh0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIGFzZXh1YWxfbG9jcykgJT4lCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAidGVtcF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiKQoKdGVtcF9zZXh1YWwgPC0KICByYXN0ZXI6OmV4dHJhY3QodGVtcF9zdGFiaWxpdHlfc2NhbGVkLCBzZXh1YWxfbG9jcykgJT4lCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAidGVtcF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgp0ZW1wX2RmIDwtIGJpbmRfcm93cyh0ZW1wX2FzZXh1YWwsIHRlbXBfc2V4dWFsKQoKIyBwbG90IHRlbXBlcmF0dXJlIHN0YWJpbGl0eQp0ZW1wX3N0YWJpbGl0eV9wbG90IDwtIGdncGxvdChkYXRhID0gdGVtcF9kZiwKICAgICAgIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSB0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIGZpbGwgPSByZXByb2R1Y3RpdmVfbW9kZSkpICsKICBnZW9tX3Zpb2xpbih3aWR0aCA9IDAuOCkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuMSwKICAgICAgICAgICAgICAgY29sb3IgPSAiZ3JheSIsCiAgICAgICAgICAgICAgIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzX2Qob3B0aW9uID0gIm1hZ21hIikgKwogIHRoZW1lX2RhcmsoKQoKdGVtcF9zdGFiaWxpdHlfcGxvdAoKIyBleHRyYWN0IG92ZXJhbGwgc3RhYmlsaXR5IHZhbHVlcyBhbmQgYmluZCBpbnRvIGEgZGF0YWZyYW1lCm92ZXJhbGxfYXNleHVhbCA8LQogIHJhc3Rlcjo6ZXh0cmFjdChvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQsIGFzZXh1YWxfbG9jcykgJT4lCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAib3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiKQoKb3ZlcmFsbF9zZXh1YWwgPC0KICByYXN0ZXI6OmV4dHJhY3Qob3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkLCBzZXh1YWxfbG9jcykgJT4lCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAib3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgpvdmVyYWxsX2RmIDwtIGJpbmRfcm93cyhvdmVyYWxsX2FzZXh1YWwsIG92ZXJhbGxfc2V4dWFsKQoKIyBwbG90IG92ZXJhbGwgc3RhYmlsaXR5Cm92ZXJhbGxfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KAogIGRhdGEgPSBvdmVyYWxsX2RmLAogIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSBvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQsIGZpbGwgPSByZXByb2R1Y3RpdmVfbW9kZSkKKSArCiAgZ2VvbV92aW9saW4od2lkdGggPSAwLjgpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjEsCiAgICAgICAgICAgICAgIGNvbG9yID0gImdyYXkiLAogICAgICAgICAgICAgICBmaWxsID0gInRyYW5zcGFyZW50IikgKwogIHNjYWxlX2ZpbGxfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCm92ZXJhbGxfc3RhYmlsaXR5X3Bsb3QKCmdnc2F2ZSgidGVtcF9zdGFiaWxpdHlfcGxvdC5wbmciLAogICAgICAgcGxvdCA9IHRlbXBfc3RhYmlsaXR5X3Bsb3QsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCmdnc2F2ZSgicHJlY2lwX3N0YWJpbGl0eV9wbG90LnBuZyIsCiAgICAgICBwbG90ID0gcHJlY2lwX3N0YWJpbGl0eV9wbG90LAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgpnZ3NhdmUoIm92ZXJhbGxfc3RhYmlsaXR5X3Bsb3QucG5nIiwKICAgICAgIHBsb3QgPSBvdmVyYWxsX3N0YWJpbGl0eV9wbG90LAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCmBgYAoKCgojIyBQQ0EtU3BlY2llcyB7LnRhYnNldH0KVGhlc2UgYXJlIFBDQXMgb2YgZW52aXJvbm1lbnRhbCBzcGFjZSBmb3Igc3BlY2llcyB3aXRoaW4gZ2VuZXJhLiBFYWNoIGNsaW1hdGUgUENBIGlzIG9mIGxvY2FsaXRpZXMgZm9yIGEgc2luZ2xlIGdlbnVzLCBjb2xvcmVkIGJ5IHNwZWNpZXMuIEknbSBkb2luZyB0aGlzIGV2ZW4gZm9yIGdlbmVyYSB3aXRoIG9uZSBzcGVjaWVzLCBzbyBpdCdzIGVhc3kgdG8gc2VlIGlmIGNlcnRhaW4gbG9jYWxpdGllcyBncm91cCB0b2dldGhlci4gCgojIyMgQWNhbnRob3h5bGEKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiNzb3VyY2UgZnVuY3Rpb24gdG8gY29uZHVjdCBhIFBDQSBvbiBpbmRpdmlkdWFsIHNwZWNpZXMKc3VtbWFyeV9saXN0X2FjYW4gPC0gc3BlY2llc19wY2FfZnVuKGxvY19jbGltLCAiYWNhbnRob3h5bGEiKQojcGxvdAphY2FuX3Bsb3QgPC0gcGxvdF9jbGltX3BjYShzdW1tYXJ5X2xpc3RfYWNhbiRsb2NfY2xpbSwgc3VtbWFyeV9saXN0X2FjYW4kc3VtbWFyeV9wY2EsICJyZXByb2R1Y3RpdmVfbW9kZSIpCgphY2FuX3Bsb3QKCiMgc2F2ZSBwY2EgcGxvdApodG1sd2lkZ2V0czo6c2F2ZVdpZGdldChhY2FuX3Bsb3QsIGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCAiYWNhbnRob3h5bGFfcGNhLmh0bWwiKSwgc2VsZmNvbnRhaW5lZCA9IFRSVUUpCgojZmlsdGVyIGxvY2FsaXRpZXMgZm9yIHRoZSBmb2NhbCBnZW51cwphY2FuX2xvYyA8LSBsb2MgJT4lIAogIGZpbHRlcihnZW51cyA9PSAiYWNhbnRob3h5bGEiKQogIAojdXNlIHNvdXJjZWQgcGxvdF9sb2NzX2xlYWZsZXQgc2NyaXB0IHRvIHBsb3QgbG9jYWxpdGllcwphY2FuX21hcCA8LSBwbG90X2xvY3NfbGVhZmxldChhY2FuX2xvYywgInJlcHJvZHVjdGl2ZV9tb2RlIikKCmFjYW5fbWFwCgojIHNhdmUgdGhlIG1hcAptYXB2aWV3OjptYXBzaG90KGFjYW5fbWFwLCB1cmwgPSBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgImFjYW5fbWFwLmh0bWwiKSwgZmlsZSA9IGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCJhY2FuX21hcC5wZGYiKSkKYGBgCgoKYGBge3J9CnN1bW1hcnlfbGlzdF9hY2FuJHN1bW1hcnlfcGNhCmxvYWRpbmdzX2FjYW4gPC0gc3VtbWFyeV9saXN0X2FjYW4kc3VtbWFyeV9wY2Ekcm90YXRpb24Ka25pdHI6OmthYmxlKHJvdW5kKGxvYWRpbmdzX2FjYW5bLDE6M10sMykpICNUYWJsZSBvZiBsb2FkaW5nIHNjb3JlcyBmb3IgdGhlIGZpcnN0IDMgUENzLiAKYGBgCgoKIyMjIEFyZ29zYXJjaHVzCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgY29uZHVjdCBwY2EKc3VtbWFyeV9saXN0X2FyZ28gPC0gc3BlY2llc19wY2FfZnVuKGxvY19jbGltLCAiYXJnb3NhcmNodXMiKQoKIyBwbG90CmFyZ29fcGxvdCA8LQogIHBsb3RfY2xpbV9wY2Eoc3VtbWFyeV9saXN0X2FyZ28kbG9jX2NsaW0sCiAgICAgICAgICAgICAgICBzdW1tYXJ5X2xpc3RfYXJnbyRzdW1tYXJ5X3BjYSwKICAgICAgICAgICAgICAgIGZhY3RvciA9ICJyZXByb2R1Y3RpdmVfbW9kZSIpCmFyZ29fcGxvdAoKaHRtbHdpZGdldHM6OnNhdmVXaWRnZXQoYXJnb19wbG90LAogICAgICAgICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgImFob3JfcGNhLmh0bWwiKSwKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZmNvbnRhaW5lZCA9IFRSVUUpCgojZmlsdGVyIGxvY2FsaXRpZXMgZm9yIHRoZSBmb2NhbCBnZW51cwphcmdvX2xvYyA8LSBsb2MgJT4lCiAgZmlsdGVyKGdlbnVzID09ICJhcmdvc2FyY2h1cyIpCgojdXNlIHNvdXJjZWQgcGxvdF9sb2NzX2xlYWZsZXQgc2NyaXB0IHRvIHBsb3QgbG9jYWxpdGllcwphcmdvX21hcCA8LSBwbG90X2xvY3NfbGVhZmxldChhcmdvX2xvYywgInJlcHJvZHVjdGl2ZV9tb2RlIikKCmFyZ29fbWFwCgptYXB2aWV3OjptYXBzaG90KAogIGFyZ29fbWFwLAogIHVybCA9IGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCAiYWhvcl9tYXAuaHRtbCIpLAogIGZpbGUgPSBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgImFob3JfbWFwLnBkZiIpCikKCgpgYGAKCmBgYHtyfQpzdW1tYXJ5X2xpc3RfYXJnbyRzdW1tYXJ5X3BjYQpsb2FkaW5nc19hcmdvIDwtIHN1bW1hcnlfbGlzdF9hcmdvJHN1bW1hcnlfcGNhJHJvdGF0aW9uCmtuaXRyOjprYWJsZShyb3VuZChsb2FkaW5nc19hcmdvWywgMTozXSwgMykpICNUYWJsZSBvZiBsb2FkaW5nIHNjb3JlcyBmb3IgdGhlIGZpcnN0IDMgUENzLiAKYGBgCgpOb3cgSSdtIGdvaW5nIHRvIHRvIGVudmlyb25tZW50YWwgbmljaGUgZmFjdG9yIGFuYWx5c2lzIGJldHdlZW4gc2V4dWFsIGFuZCBhc2V4dWFsIHBvcHVsYXRpb25zIHdpdGhpbiB0aGUgc3BlY2llcy4KYGBge3Igd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KI2dldCBiYWNrZ3JvdW5kIGVudid0IGZvciB0aGUgc3BlY2llcwphaG9yX2JnX2VudiA8LSBiZ19lbnZfY3JvcChhcmdvX2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXMgPSAiaG9ycmlkdXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBlbnZpcm9ubWVudCA9IHcsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIgPSAwLjUpCgojZW5mYSBmb3IgdGhlIHNleHVhbCBzcGVjaWVzCmFob3Jfc2V4dWFsX2VuZmEgPC0gZW5mYV9jYWxjX2Z1bihsb2NzID0gYXJnb19sb2MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJob3JyaWR1cyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXNrX3Jhc3RlciA9IGFob3JfYmdfZW52KQoKI2VuZmEgZm9yIHRoZSBhc2V4dWFsIHNwZWNpZXMKYWhvcl9hc2V4dWFsX2VuZmEgPC0gZW5mYV9jYWxjX2Z1bihsb2NzID0gYXJnb19sb2MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXMgPSAiaG9ycmlkdXMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFza19yYXN0ZXIgPSBhaG9yX2JnX2VudikKCgojcGxvdCB0aGUgbWFyZ2luYWxpdHkgc2NvcmVzCmFob3JfbWFyZ2luYWxpdHkgPC0gbWFyZ2luYWxpdHlfbG9sbGlwb3Aoc2V4X21hcmcgPSBhaG9yX3NleHVhbF9lbmZhJG0sIAogICAgICAgICAgICAgICAgICAgIGFzZXhfbWFyZyA9IGFob3JfYXNleHVhbF9lbmZhJG0sCiAgICAgICAgICAgICAgICAgICAgZnVsbF9zcGVjaWVzX25hbWUgPSAiQXJnb3NhcmNodXMgaG9ycmlkdXMiKQoKIyB3cml0ZSBzY29yZXMgdG8gY3N2cwpyZWFkcjo6d3JpdGVfY3N2KAogIGFob3JfYXNleHVhbF9lbmZhJG0gJT4lIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm1hcmdpbmFsaXR5IiksCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWhvcl9hc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgYWhvcl9zZXh1YWxfZW5mYSRtICU+JSBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJtYXJnaW5hbGl0eSIpLAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImFob3Jfc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCmdnc2F2ZSgiYWhvcl9tYXJnaW5hbGl0eV9sb2xsaXBvcC5wbmciLAogICAgICAgcGxvdCA9IGFob3JfbWFyZ2luYWxpdHksCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCgpgYGAKCkEgY291cGxlIGRpZmZlcmVudCB3YXlzIHRvIHZpc3VhbGl6ZSB0aGUgZW52aXJvbm1lbnRhbCB2YXJpYXRpb24uIDEpIFNjYXR0ZXJwbG90IHZpc3VhbGl6YXRpb25zIG9mIG1hcmdpbmFsaXR5IHZzIGF4aXMgMSBvZiB0aGUgc3BlY2lhbGl6YXRpb24gd2l0aCB0aGUgbGFiZWxzIHJlbW92ZWQgKHRoZXkgbWFrZSB0aGluZ3MgaW5kaXNjZXJuYWJsZSkuIFJlZCA9IG9jY3VwaWVkIGUtc3BhY2UuIEdyYXkgPSBCYWNrZ3JvdW5kIGUtc3BhY2UuIFRoZSB5ZWxsb3cgZG90IGluZGljYXRlcyB0aGUgbWVhbiBtYXJnaW5hbGl0eSAoaXQncyBub3QgdGhlIHZhbHVlIHRoYXQgaXMgb24gdGhlIGxvbGxpcG9wIHBsb3QsIHNvIGRvbid0IGxldCB0aGF0IGNvbmZ1c2UgeW91KS4gMikgRU5GQSBoaXN0b2dyYW0gdmlzdWFsaXphdGlvbnMgb2YgbWFyZ2luYWxpdHkgYW5kIHNwZWNpYWxpemF0aW9uIGF4ZXMuIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlIHdpdGggY29sb3JzIGNvcnJlc3BvbmRpbmcgdG8gc2V4dWFsIHZzLiBhc2V4dWFsIHBvcHVsYXRpb25zLiAKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMjIyAxKSBFTkZBIHNjYXR0ZXJwbG90CiNhY2Nlc3MgdGhlIHJlbGV2YW50IHZhbHVlcyBmb3IgcGxvdHRpbmcKYWhvcl9hc2V4dWFsX2RmIDwtIGFob3JfYXNleHVhbF9lbmZhJGxpICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgYmluZF9jb2xzKHByID0gYWhvcl9hc2V4dWFsX2VuZmEkcHIpCgpyZWFkcjo6d3JpdGVfY3N2KGFob3JfYXNleHVhbF9kZiwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWhvcl9hc2V4dWFsX21hcmdpbmFsaXR5X2RmLmNzdiIpKQoKYWhvcl9zZXh1YWxfZGYgPC0gYWhvcl9zZXh1YWxfZW5mYSRsaSAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGJpbmRfY29scyhwciA9IGFob3Jfc2V4dWFsX2VuZmEkcHIpCgpyZWFkcjo6d3JpdGVfY3N2KGFob3Jfc2V4dWFsX2RmLCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJhaG9yX3NleHVhbF9tYXJnaW5hbGl0eV9kZi5jc3YiKSkKCiNhc2V4dWFsCmFob3JfZW5mYV9zcGVjX2FzZXh1YWwgPC0gZW5mYV9oZXhfcGxvdChhaG9yX2FzZXh1YWxfZGYsIG1hcmcgPSBNYXIsIHNwZWMgPSBTcGUxLCByZXByb19tb2RlID0gIkFzZXh1YWwiKQoKYWhvcl9lbmZhX3NwZWNfYXNleHVhbAoKZ2dzYXZlKCJhaG9yX2VuZmFfc3BlY19hc2V4dWFsLnBuZyIsCiAgICAgICBwbG90ID0gYWhvcl9lbmZhX3NwZWNfYXNleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKI3NleHVhbAphaG9yX2VuZmFfc3BlY19zZXh1YWwgPC0gZW5mYV9oZXhfcGxvdChhaG9yX3NleHVhbF9kZiwgbWFyZyA9IE1hciwgc3BlYyA9IFNwZTEsIHJlcHJvX21vZGUgPSAiU2V4dWFsIikKCmFob3JfZW5mYV9zcGVjX3NleHVhbAoKZ2dzYXZlKCJhaG9yX2VuZmFfc3BlY19zZXh1YWwucG5nIiwKICAgICAgIHBsb3QgPSBhaG9yX2VuZmFfc3BlY19zZXh1YWwsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMjIyAyKSBFTkZBIGhpc3RvZ3JhbQojIyBhc2V4dWFsCmhpc3QoYWhvcl9hc2V4dWFsX2VuZmEpCnRpdGxlKG1haW4gPSAiQXNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCiMgd3JpdGUgdG8gZmlsZQpwbmcoZmlsZW5hbWUgPSBmaWxlLnBhdGgocGxvdF9wYXRoLCAiYWhvcl9hc2V4dWFsX2VuZmFfaGlzdC5wbmciKSkKaGlzdChhaG9yX2FzZXh1YWxfZW5mYSkKdGl0bGUobWFpbiA9ICJBc2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQpkZXYub2ZmKCkKCiMjIHNleHVhbApoaXN0KGFob3Jfc2V4dWFsX2VuZmEpCnRpdGxlKG1haW4gPSAiU2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQoKIyB3cml0ZSB0byBmaWxlCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJhaG9yX3NleHVhbF9lbmZhX2hpc3QucG5nIikpCmhpc3QoYWhvcl9zZXh1YWxfZW5mYSkKdGl0bGUobWFpbiA9ICJTZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKIyMjIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlCmFob3JfdG90YWxfcGNhIDwtIHRvdGFsX2NsaW1hdGVfcGNhX3Bsb3QoYmdfZW52ID0gYWhvcl9iZ19lbnYsIGxvY3MgPSBhcmdvX2xvYywgZ2VudXMgPSAiQXJnb3NhcmNodXMiLCBzcGVjaWVzID0gImhvcnJpZHVzIikKCmFob3JfdG90YWxfcGNhCgpnZ3NhdmUoImFob3JfdG90YWxfcGNhLnBuZyIsCiAgICAgICBwbG90ID0gYWhvcl90b3RhbF9wY2EsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKYGBgCgoKVHJ5aW5nIG91dCBhIHJlcGVhdCBvZiB0aGUgYW5hbHlzZXMgd2l0aCByZWR1Y2VkIGVudmlyb25tZW50YWwgc3BhY2UuClByaW9yaXRpemluZyB2YXJpYWJsZXMgdGhhdCB3aWxsIGxpbWl0IHRoZWlyIGRpc3RyaWJ1dGlvbiAoaS5lLiB2YXJpYWJsZXMgdGhhdCByZXByZXNlbnQgdGhlIGV4dHJlbWVzKS4gQWZ0ZXIgY29ycmVsYXRpb24gYW5hbHlzaXMsIHdlJ3JlIGxlZnQgd2l0aCBCSU82LCBCSU8xMywgQklPMTQsIEJJTzE2CmBgYHtyIGNhY2hlPVRSVUV9CiMgUENBIG9mIGJhY2tncm91bmQgZS1zcGFjZS4gUmVzdWx0aW5nIGxpc3QgaXMgYSBjb3JyZWxhdGlvbiBoZWF0bWFwIChjb3JfaGVhdG1hcCksIGEgdGliYmxlIG9mIHRoZSByYXN0ZXJzIHdpdGggY29ycmVsYXRpb24gPiB0aGUgY3V0b2ZmIChkZWZhdWx0IGlzIDAuNzUpLCBhbmQgYSB0aWJibGUgb2YgYWxsIHBhaXJ3aXNlIGNvcnJlbGF0aW9ucwphaG9yX3BjYSA8LSByYXN0ZXJfY29ycmVsYXRpb24ocmFzdGVyX3N0YWNrID0gYWhvcl9iZ19lbnYpCmFob3JfcGNhJGNvcl9oZWF0bWFwCmFob3JfcGNhJHRvcF9jb3IgJT4lIGtuaXRyOjprYWJsZSgpCgpnZ3NhdmUoImFob3JfcGNhX2NvcnIucG5nIiwKICAgICAgIHBsb3QgPSBhaG9yX3BjYSRjb3JfaGVhdG1hcCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKCiMgd3JpdGUgY29ycmVsYXRpb24gZGF0YSBmcmFtZSB0byBmaWxlCnJlYWRyOjp3cml0ZV9jc3YoYWhvcl9wY2EkdG9wX2NvciwgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWhvcl90b3BfY29yLmNzdiIpKQpgYGAKClJlcGVhdCB0aGUgYW5hbHlzaXMgd2l0aCB0aGUgcmVkdWNlZCBkYXRhIHNldC4gVGhlIGJhY2tncm91bmQgZW52aXJvbm1lbnQgaXMgMC41IGRlZ3JlZXMsIGEgYmFsbHBhcmsgZGlzcGVyc2FsIGxpbWl0YXRpb24gZm9yIGFsbCBzdGljayBpbnNlY3Qgc3BlY2llcyBpbiB0aGlzIHN0dWR5LgpgYGB7cn0Kd19haG9yIDwtIHJhc3Rlcjo6c3Vic2V0KHcsIGMoImJpbzYiLCAiYmlvMTMiLCAiYmlvMTQiLCAiYmlvMTYiKSkKCiNnZXQgYmFja2dyb3VuZCBlbnYndCBmb3IgdGhlIHNwZWNpZXMKYWhvcl9iZ19lbnZfc3Vic2V0IDwtIGJnX2Vudl9jcm9wKGFyZ29fbG9jLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJob3JyaWR1cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudmlyb25tZW50ID0gd19haG9yLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyID0gMC41KQoKI2VuZmEgZm9yIHRoZSBzZXh1YWwgc3BlY2llcwphaG9yX3NleHVhbF9lbmZhX3N1YnNldCA8LSBlbmZhX2NhbGNfZnVuKGxvY3MgPSBhcmdvX2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzID0gImhvcnJpZHVzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hc2tfcmFzdGVyID0gYWhvcl9iZ19lbnZfc3Vic2V0KQoKI2VuZmEgZm9yIHRoZSBhc2V4dWFsIHNwZWNpZXMKYWhvcl9hc2V4dWFsX2VuZmFfc3Vic2V0IDwtIGVuZmFfY2FsY19mdW4obG9jcyA9IGFyZ29fbG9jLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzID0gImhvcnJpZHVzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hc2tfcmFzdGVyID0gYWhvcl9iZ19lbnZfc3Vic2V0KQoKIyB3cml0ZSBtYXJnaW5hbGl0eSBzY29yZXMgdG8gY3N2CnJlYWRyOjp3cml0ZV9jc3YoCiAgYWhvcl9hc2V4dWFsX2VuZmFfc3Vic2V0JG0gJT4lIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm1hcmdpbmFsaXR5IiksCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWhvcl9zdWJzZXRfYXNleHVhbF9tYXJnaW5hbGl0eV9zY29yZS5jc3YiKQopCgpyZWFkcjo6d3JpdGVfY3N2KAogIGFob3Jfc2V4dWFsX2VuZmFfc3Vic2V0JG0gJT4lIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm1hcmdpbmFsaXR5IiksCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWhvcl9zdWJzZXRfc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCiNwbG90IHRoZSBtYXJnaW5hbGl0eSBzY29yZXMKYWhvcl9zdWJzZXRfbWFyZ2luYWxpdHkgPC0KICBtYXJnaW5hbGl0eV9sb2xsaXBvcCgKICAgIHNleF9tYXJnID0gYWhvcl9zZXh1YWxfZW5mYV9zdWJzZXQkbSwKICAgIGFzZXhfbWFyZyA9IGFob3JfYXNleHVhbF9lbmZhX3N1YnNldCRtLAogICAgZnVsbF9zcGVjaWVzX25hbWUgPSAiQXJnb3NhcmNodXMgaG9ycmlkdXMiCiAgKQoKYWhvcl9zdWJzZXRfbWFyZ2luYWxpdHkKCmdnc2F2ZSgiYWhvcl9zdWJzZXRfbWFyZ2luYWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSBhaG9yX3N1YnNldF9tYXJnaW5hbGl0eSwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKYGBgCgpWaXN1YWxpemUgd2l0aCByZWR1Y2VkIGRhdGEgc2V0CmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMjIyAxKSBFTkZBIHNjYXR0ZXJwbG90CiNhY2Nlc3MgdGhlIHJlbGV2YW50IHZhbHVlcyBmb3IgcGxvdHRpbmcKYWhvcl9hc2V4dWFsX2RmX3N1YnNldCA8LSBhaG9yX2FzZXh1YWxfZW5mYV9zdWJzZXQkbGkgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgYmluZF9jb2xzKHByID0gYWhvcl9hc2V4dWFsX2VuZmFfc3Vic2V0JHByKQoKcmVhZHI6OndyaXRlX2NzdigKICBhaG9yX2FzZXh1YWxfZGZfc3Vic2V0LAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImFob3Jfc3Vic2V0X2FzZXh1YWxfbWFyZ2luYWxpdHlfZGYuY3N2IikKKQoKYWhvcl9zZXh1YWxfZGZfc3Vic2V0IDwtIGFob3Jfc2V4dWFsX2VuZmFfc3Vic2V0JGxpICU+JQogIGFzX3RpYmJsZSgpICU+JQogIGJpbmRfY29scyhwciA9IGFob3Jfc2V4dWFsX2VuZmFfc3Vic2V0JHByKQoKcmVhZHI6OndyaXRlX2NzdigKICBhaG9yX3NleHVhbF9kZl9zdWJzZXQsCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWhvcl9zdWJzZXRfc2V4dWFsX21hcmdpbmFsaXR5X2RmLmNzdiIpCikKCiNhc2V4dWFsLiBKZXN1cyB0aGVzZSB2YXJpYWJsZSBuYW1lcyBhcmUgZ2V0dGluZyBsb25nCmFob3Jfc3Vic2V0X2VuZmFfc3BlY19hc2V4dWFsIDwtCiAgZW5mYV9oZXhfcGxvdCgKICAgIGFob3JfYXNleHVhbF9kZl9zdWJzZXQsCiAgICBtYXJnID0gTWFyLAogICAgc3BlYyA9IFNwZTEsCiAgICByZXByb19tb2RlID0gIkFzZXh1YWwiCiAgKQoKYWhvcl9zdWJzZXRfZW5mYV9zcGVjX2FzZXh1YWwKCmdnc2F2ZSgKICAiYWhvcl9zdWJzZXRfZW5mYV9zcGVjX2FzZXh1YWwucG5nIiwKICBwbG90ID0gYWhvcl9zdWJzZXRfZW5mYV9zcGVjX2FzZXh1YWwsCiAgZGV2aWNlID0gInBuZyIsCiAgcGF0aCA9IHBsb3RfcGF0aCwKICBkcGkgPSAicmV0aW5hIgopCgojIHNleHVhbAphaG9yX3N1YnNldF9lbmZhX3NwZWNfc2V4dWFsIDwtCiAgZW5mYV9oZXhfcGxvdCgKICAgIGFob3Jfc2V4dWFsX2RmX3N1YnNldCwKICAgIG1hcmcgPSBNYXIsCiAgICBzcGVjID0gU3BlMSwKICAgIHJlcHJvX21vZGUgPSAiU2V4dWFsIgogICkKCmFob3Jfc3Vic2V0X2VuZmFfc3BlY19zZXh1YWwKCmdnc2F2ZSgKICAiYWhvcl9zdWJzZXRfZW5mYV9zcGVjX3NleHVhbC5wbmciLAogIHBsb3QgPSBhaG9yX3N1YnNldF9lbmZhX3NwZWNfc2V4dWFsLAogIGRldmljZSA9ICJwbmciLAogIHBhdGggPSBwbG90X3BhdGgsCiAgZHBpID0gInJldGluYSIKKQoKIyMjIDIpIEVORkEgaGlzdG9ncmFtCiMgYXNleHVhbApoaXN0KGFob3JfYXNleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJBc2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQoKcG5nKGZpbGVuYW1lID0gZmlsZS5wYXRoKHBsb3RfcGF0aCwgImFob3Jfc3Vic2V0X2FzZXh1YWxfZW5mYV9oaXN0LnBuZyIpKQpoaXN0KGFob3JfYXNleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJBc2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQpkZXYub2ZmKCkKCiMgc2V4dWFsCmhpc3QoYWhvcl9zZXh1YWxfZW5mYV9zdWJzZXQpCnRpdGxlKG1haW4gPSAiU2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQoKcG5nKGZpbGVuYW1lID0gZmlsZS5wYXRoKHBsb3RfcGF0aCwgImFob3Jfc3Vic2V0X3NleHVhbF9lbmZhX2hpc3QucG5nIikpCmhpc3QoYWhvcl9zZXh1YWxfZW5mYV9zdWJzZXQpCnRpdGxlKG1haW4gPSAiU2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQpkZXYub2ZmKCkKCiMjIyAzKSBQQ0Egb2YgdG90YWwgZS1zcGFjZQphaG9yX3N1YnNldF90b3RhbF9wY2EgPC0KICB0b3RhbF9jbGltYXRlX3BjYV9wbG90KAogICAgYmdfZW52ID0gYWhvcl9iZ19lbnZfc3Vic2V0LAogICAgbG9jcyA9IGFyZ29fbG9jLAogICAgZ2VudXMgPSAiQXJnb3NhcmNodXMiLAogICAgc3BlY2llcyA9ICJob3JyaWR1cyIKICApCgphaG9yX3N1YnNldF90b3RhbF9wY2EKCmdnc2F2ZSgKICAiYWhvcl9zdWJzZXRfdG90YWxfcGNhLnBuZyIsCiAgcGxvdCA9IGFob3Jfc3Vic2V0X3RvdGFsX3BjYSwKICBkZXZpY2UgPSAicG5nIiwKICBwYXRoID0gcGxvdF9wYXRoLAogIGRwaSA9ICJyZXRpbmEiCikKCiMgc2F2ZSBlbmZhIG9iamVjdHMgYW5kIHJlbW92ZSB0aGVtIGZyb20gdGhlIGVudmlyb25tZW50LiBUaGV5IHRha2UgdXAgYSBsb3Qgb2YgbWVtb3J5LgpzYXZlUkRTKGFob3Jfc2V4dWFsX2VuZmEsIGZpbGUgPSBmaWxlLnBhdGgob2JqX3BhdGgsICJhaG9yX3NleHVhbF9lbmZhLlJEUyIpKQpybShhaG9yX3NleHVhbF9lbmZhKQoKc2F2ZVJEUyhhaG9yX2FzZXh1YWxfZW5mYSwgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgImFob3JfYXNleHVhbF9lbmZhLlJEUyIpKQpybShhaG9yX2FzZXh1YWxfZW5mYSkKCnNhdmVSRFMoYWhvcl9zZXh1YWxfZW5mYV9zdWJzZXQsCiAgICAgICAgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgImFob3Jfc3Vic2V0X3NleHVhbF9lbmZhLlJEUyIpKQpybShhaG9yX3NleHVhbF9lbmZhX3N1YnNldCkKCnNhdmVSRFMoYWhvcl9hc2V4dWFsX2VuZmFfc3Vic2V0LAogICAgICAgIGZpbGUgPSBmaWxlLnBhdGgob2JqX3BhdGgsICJhaG9yX3N1YnNldF9hc2V4dWFsX2VuZmEuUkRTIikpCnJtKGFob3JfYXNleHVhbF9lbmZhX3N1YnNldCkKYGBgCgoKV2UncmUgYWxzbyBpbnRlcmVzdGVkIGluIHNlZWluZyBpZiBhc2V4dWFsIHBvcHVsYXRpb25zIGxpdmUgaW4gbW9yZSB1bnN0YWJsZSBjbGltYXRpYyBhcmVhcyByZWxhdGl2ZSB0byBzZXh1YWwgcG9wdWxhdGlvbnMuIApgYGB7cn0KYXJnb19sb2NzX2FzZXh1YWwgPC0gYXJnb19sb2MgJT4lIAogIG11dGF0ZShsYXRfbG9uZyA9IHN0cl9jKGxhdGl0dWRlLCBsb25naXR1ZGUsIHNlcCA9ICJfIikpICU+JSAKICBmaWx0ZXIocmVwcm9kdWN0aXZlX21vZGUgPT0gImFzZXh1YWwiLAogICAgICAgICAhZHVwbGljYXRlZChsYXRfbG9uZykpICU+JSAKICBkcGx5cjo6c2VsZWN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUpCgphcmdvX2xvY3Nfc2V4dWFsIDwtIGFyZ29fbG9jICU+JSAKICBtdXRhdGUobGF0X2xvbmcgPSBzdHJfYyhsYXRpdHVkZSwgbG9uZ2l0dWRlLCBzZXAgPSAiXyIpKSAlPiUgCiAgZmlsdGVyKHJlcHJvZHVjdGl2ZV9tb2RlID09ICJzZXh1YWwiLAogICAgICAgICAhZHVwbGljYXRlZChsYXRfbG9uZykpICU+JSAKICBkcGx5cjo6c2VsZWN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUpCgpwcmVjaXBfYXNleHVhbF9haG9yIDwtIHJhc3Rlcjo6ZXh0cmFjdChwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCwgYXJnb19sb2NzX2FzZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIpCgpwcmVjaXBfc2V4dWFsX2Fob3IgPC0gcmFzdGVyOjpleHRyYWN0KHByZWNpcF9zdGFiaWxpdHlfc2NhbGVkLCBhcmdvX2xvY3Nfc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAicHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgpwcmVjaXBfZGZfYWhvciA8LSBiaW5kX3Jvd3MocHJlY2lwX2FzZXh1YWxfYWhvciwgcHJlY2lwX3NleHVhbF9haG9yKQoKcmVhZHI6OndyaXRlX2NzdihwcmVjaXBfZGZfYWhvciwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWhvcl9wcmVjaXBfc3RhYmlsaXR5X2RmLmNzdiIpKQoKYWhvcl9wcmVjaXBfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBwcmVjaXBfZGZfYWhvciwgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IHByZWNpcF9zdGFiaWxpdHlfc2NhbGVkLCBjb2xvciA9IHJlcHJvZHVjdGl2ZV9tb2RlKSkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuNSwgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gInRyYW5zcGFyZW50IikgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBhbHBoYSA9IDAuNikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAibWFnbWEiKSArCiAgdGhlbWVfZGFyaygpCgphaG9yX3ByZWNpcF9zdGFiaWxpdHlfcGxvdAoKZ2dzYXZlKAogICJhaG9yX3ByZWNpcF9zdGFiaWxpdHkucG5nIiwKICBwbG90ID0gYWhvcl9wcmVjaXBfc3RhYmlsaXR5X3Bsb3QsCiAgZGV2aWNlID0gInBuZyIsCiAgcGF0aCA9IHBsb3RfcGF0aCwKICBkcGkgPSAicmV0aW5hIgopCgp0ZW1wX2FzZXh1YWxfYWhvciA8LSByYXN0ZXI6OmV4dHJhY3QodGVtcF9zdGFiaWxpdHlfc2NhbGVkLCBhcmdvX2xvY3NfYXNleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInRlbXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIpCgp0ZW1wX3NleHVhbF9haG9yIDwtIHJhc3Rlcjo6ZXh0cmFjdCh0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIGFyZ29fbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJ0ZW1wX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgp0ZW1wX2RmX2Fob3IgPC0gYmluZF9yb3dzKHRlbXBfYXNleHVhbF9haG9yLCB0ZW1wX3NleHVhbF9haG9yKQoKcmVhZHI6OndyaXRlX2Nzdih0ZW1wX2RmX2Fob3IsIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImFob3JfdGVtcF9zdGFiaWxpdHlfZGYuY3N2IikpCgphaG9yX3RlbXBfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSB0ZW1wX2RmX2Fob3IsIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSB0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIGNvbG9yID0gcmVwcm9kdWN0aXZlX21vZGUpKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC41LCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFscGhhID0gMC42KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCmFob3JfdGVtcF9zdGFiaWxpdHlfcGxvdAoKZ2dzYXZlKAogICJhaG9yX3RlbXBfc3RhYmlsaXR5LnBuZyIsCiAgcGxvdCA9IGFob3JfdGVtcF9zdGFiaWxpdHlfcGxvdCwKICBkZXZpY2UgPSAicG5nIiwKICBwYXRoID0gcGxvdF9wYXRoLAogIGRwaSA9ICJyZXRpbmEiCikKCm92ZXJhbGxfYXNleHVhbF9haG9yIDwtIHJhc3Rlcjo6ZXh0cmFjdChvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQsIGFyZ29fbG9jc19hc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAib3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCm92ZXJhbGxfc2V4dWFsX2Fob3IgPC0gcmFzdGVyOjpleHRyYWN0KG92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCwgYXJnb19sb2NzX3NleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIikKCm92ZXJhbGxfZGZfYWhvciA8LSBiaW5kX3Jvd3Mob3ZlcmFsbF9hc2V4dWFsX2Fob3IsIG92ZXJhbGxfc2V4dWFsX2Fob3IpCgpyZWFkcjo6d3JpdGVfY3N2KG92ZXJhbGxfZGZfYWhvciwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWhvcl9vdmVyYWxsX3N0YWJpbGl0eV9kZi5jc3YiKSkKCgphaG9yX292ZXJhbGxfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBvdmVyYWxsX2RmX2Fob3IsIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSBvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQsIGNvbG9yID0gcmVwcm9kdWN0aXZlX21vZGUpKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC41LCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFscGhhID0gMC42KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCmFob3Jfb3ZlcmFsbF9zdGFiaWxpdHlfcGxvdAoKZ2dzYXZlKAogICJhaG9yX292ZXJhbGxfc3RhYmlsaXR5LnBuZyIsCiAgcGxvdCA9IGFob3Jfb3ZlcmFsbF9zdGFiaWxpdHlfcGxvdCwKICBkZXZpY2UgPSAicG5nIiwKICBwYXRoID0gcGxvdF9wYXRoLAogIGRwaSA9ICJyZXRpbmEiCikKCmBgYAoKClB1dCBhbGwgb3V0cHV0IGludG8gc3BlY2llcy1zcGVjaWZpYyBzdWJmb2xkZXJzLgpgYGB7ciByZXN1bHRzPSJoaWRlIn0KYWhvcl9vdXRfaW50X3BhdGggPC0gZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJhcmdvc2FyY2h1c19ob3JyaWR1cyIpCmFob3Jfb3V0X3Bsb3RfcGF0aCA8LSBmaWxlLnBhdGgocGxvdF9wYXRoLCAiYXJnb3NhcmNodXNfaG9ycmlkdXMiKQphaG9yX291dF9zcHJlYWRfcGF0aCA8LSBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJhcmdvc2FyY2h1c19ob3JyaWR1cyIpCmFob3Jfb3V0X29ial9wYXRoIDwtIGZpbGUucGF0aChvYmpfcGF0aCwgImFyZ29zYXJjaHVzX2hvcnJpZHVzIikKCiMgbW92ZSBpbnRlcmFjdGl2ZQptb3ZlX3RvX3NwZWNpZXMoaW5fcGF0aCA9IGludGVyYWN0aXZlX3BhdGgsCiAgICAgICAgICAgICAgICBvdXRfcGF0aCA9IGFob3Jfb3V0X2ludF9wYXRoLAogICAgICAgICAgICAgICAgcGF0dGVybiA9ICJhaG9yIikKIyBtb3ZlIHBsb3RzCm1vdmVfdG9fc3BlY2llcyhpbl9wYXRoID0gcGxvdF9wYXRoLAogICAgICAgICAgICAgICAgb3V0X3BhdGggPSBhaG9yX291dF9wbG90X3BhdGgsCiAgICAgICAgICAgICAgICBwYXR0ZXJuID0gImFob3IiKQoKIyBtb3ZlIHNwcmVhZHNoZWV0cwptb3ZlX3RvX3NwZWNpZXMoaW5fcGF0aCA9IHNwcmVhZF9wYXRoLAogICAgICAgICAgICAgICAgb3V0X3BhdGggPSBhaG9yX291dF9zcHJlYWRfcGF0aCwKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAiYWhvciIpCgojIG1vdmUgb2JqZWN0cwptb3ZlX3RvX3NwZWNpZXMoaW5fcGF0aCA9IG9ial9wYXRoLAogICAgICAgICAgICAgICAgb3V0X3BhdGggPSBhaG9yX291dF9vYmpfcGF0aCwKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAiYWhvciIpCmBgYAoKCgojIyMgQXN0ZWxpYXBoYXNtYQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojcGNhCnN1bW1hcnlfbGlzdF9hc3RlIDwtIHNwZWNpZXNfcGNhX2Z1bihsb2NfY2xpbSwgImFzdGVsaWFwaGFzbWEiKQojcGxvdAphc3RlX3Bsb3QgPC0gcGxvdF9jbGltX3BjYShzdW1tYXJ5X2xpc3RfYXN0ZSRsb2NfY2xpbSwgc3VtbWFyeV9saXN0X2FzdGUkc3VtbWFyeV9wY2EsIGZhY3RvciA9ICJyZXByb2R1Y3RpdmVfbW9kZSIpCmFzdGVfcGxvdAoKI2lmIHNlbGZjb250YWluZWQgPSBUUlVFLCB5b3UgY2FuIHJlbW92ZSB0aGUgZm9sZGVyIHRoYXQgZ2V0cyBhZGRlZCBhbG9uZ3NpZGUgdGhlIHBsb3QuIApodG1sd2lkZ2V0czo6c2F2ZVdpZGdldChhc3RlX3Bsb3QsIGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCAiYXN0ZWxpYXBoYXNtYV9wY2EuaHRtbCIpLCBzZWxmY29udGFpbmVkID0gVFJVRSkKCiNmaWx0ZXIgbG9jYWxpdGllcyBmb3IgdGhlIGZvY2FsIGdlbnVzCmFzdGVfbG9jIDwtIGxvYyAlPiUgCiAgZmlsdGVyKGdlbnVzID09ICJhc3RlbGlhcGhhc21hIikKICAKI3VzZSBzb3VyY2VkIHBsb3RfbG9jc19sZWFmbGV0IHNjcmlwdCB0byBwbG90IGxvY2FsaXRpZXMKYXN0ZV9tYXAgPC0gcGxvdF9sb2NzX2xlYWZsZXQoYXN0ZV9sb2MsICJyZXByb2R1Y3RpdmVfbW9kZSIpCgphc3RlX21hcAoKIyBzYXZlIHRoZSBtYXAKbWFwdmlldzo6bWFwc2hvdChhc3RlX21hcCwgdXJsID0gZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJhc3RlX21hcC5odG1sIiksIGZpbGUgPSBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgImFzdGVfbWFwLnBkZiIpKQoKYGBgCgoKCmBgYHtyfQpzdW1tYXJ5X2xpc3RfYXN0ZSRzdW1tYXJ5X3BjYQpsb2FkaW5nc19hc3RlIDwtIHN1bW1hcnlfbGlzdF9hc3RlJHN1bW1hcnlfcGNhJHJvdGF0aW9uCmtuaXRyOjprYWJsZShyb3VuZChsb2FkaW5nc19hc3RlWywxOjNdLDMpKSAjVGFibGUgb2YgbG9hZGluZyBzY29yZXMgZm9yIHRoZSBmaXJzdCAzIFBDcy4gCmBgYAoKCgpOb3cgSSdtIGdvaW5nIHRvIHRvIGVudmlyb25tZW50YWwgbmljaGUgZmFjdG9yIGFuYWx5c2lzIGJldHdlZW4gc2V4dWFsIGFuZCBhc2V4dWFsIHBvcHVsYXRpb25zIHdpdGhpbiB0aGUgc3BlY2llcy4KYGBge3Igd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlPUZBTFNFfQojZ2V0IGJhY2tncm91bmQgZW52J3QgZm9yIHRoZSBzcGVjaWVzCmFqdWNfYmdfZW52IDwtIGJnX2Vudl9jcm9wKGFzdGVfbG9jLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJqdWN1bmR1bSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudmlyb25tZW50ID0gdywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciA9IDAuNSkKCiNlbmZhIGZvciB0aGUgc2V4dWFsIHNwZWNpZXMKYWp1Y19zZXh1YWxfZW5mYSA8LSBlbmZhX2NhbGNfZnVuKGxvY3MgPSBhc3RlX2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzID0gImp1Y3VuZHVtIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hc2tfcmFzdGVyID0gYWp1Y19iZ19lbnYpCgojZW5mYSBmb3IgdGhlIGFzZXh1YWwgc3BlY2llcwphanVjX2FzZXh1YWxfZW5mYSA8LSBlbmZhX2NhbGNfZnVuKGxvY3MgPSBhc3RlX2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJqdWN1bmR1bSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXNrX3Jhc3RlciA9IGFqdWNfYmdfZW52KQoKCiNwbG90IHRoZSBtYXJnaW5hbGl0eSBzY29yZXMKYWp1Y19tYXJnaW5hbGl0eSA8LSAgbWFyZ2luYWxpdHlfbG9sbGlwb3Aoc2V4X21hcmcgPSBhanVjX3NleHVhbF9lbmZhJG0sIAogICAgICAgICAgICAgICAgICAgIGFzZXhfbWFyZyA9IGFqdWNfYXNleHVhbF9lbmZhJG0sCiAgICAgICAgICAgICAgICAgICAgZnVsbF9zcGVjaWVzX25hbWUgPSAiQXN0ZWxpYXBoYXNtYSBqdWN1bmR1bSIpCgphanVjX21hcmdpbmFsaXR5CgojIHdyaXRlIHNjb3JlcyB0byBjc3ZzCnJlYWRyOjp3cml0ZV9jc3YoCiAgYWp1Y19hc2V4dWFsX2VuZmEkbSAlPiUgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAibWFyZ2luYWxpdHkiKSwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJhanVjX2FzZXh1YWxfbWFyZ2luYWxpdHlfc2NvcmUuY3N2IikKKQoKcmVhZHI6OndyaXRlX2NzdigKICBhanVjX3NleHVhbF9lbmZhJG0gJT4lIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm1hcmdpbmFsaXR5IiksCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWp1Y19zZXh1YWxfbWFyZ2luYWxpdHlfc2NvcmUuY3N2IikKKQoKZ2dzYXZlKCJhanVjX21hcmdpbmFsaXR5X2xvbGxpcG9wLnBuZyIsCiAgICAgICBwbG90ID0gYWp1Y19tYXJnaW5hbGl0eSwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQpgYGAKCkEgY291cGxlIGRpZmZlcmVudCB3YXlzIHRvIHZpc3VhbGl6ZSB0aGUgZW52aXJvbm1lbnRhbCB2YXJpYXRpb24uIDEpIFNjYXR0ZXJwbG90IHZpc3VhbGl6YXRpb25zIG9mIG1hcmdpbmFsaXR5IHZzIGF4aXMgMSBvZiB0aGUgc3BlY2lhbGl6YXRpb24gd2l0aCB0aGUgbGFiZWxzIHJlbW92ZWQgKHRoZXkgbWFrZSB0aGluZ3MgaW5kaXNjZXJuYWJsZSkuIFJlZCA9IG9jY3VwaWVkIGUtc3BhY2UuIEdyYXkgPSBCYWNrZ3JvdW5kIGUtc3BhY2UuIDIpIEVORkEgaGlzdG9ncmFtIHZpc3VhbGl6YXRpb25zIG9mIG1hcmdpbmFsaXR5IGFuZCBzcGVjaWFsaXphdGlvbiBheGVzLiAzKSBQQ0Egb2YgdG90YWwgZS1zcGFjZSB3aXRoIGNvbG9ycyBjb3JyZXNwb25kaW5nIHRvIHNleHVhbCB2cy4gYXNleHVhbCBwb3B1bGF0aW9ucy4gCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMjIyAxKSBFTkZBIHNjYXR0ZXJwbG90CiNhY2Nlc3MgdGhlIHJlbGV2YW50IHZhbHVlcyBmb3IgcGxvdHRpbmcKYWp1Y19hc2V4dWFsX2RmIDwtIGFqdWNfYXNleHVhbF9lbmZhJGxpICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgYmluZF9jb2xzKHByID0gYWp1Y19hc2V4dWFsX2VuZmEkcHIpCgpyZWFkcjo6d3JpdGVfY3N2KGFqdWNfYXNleHVhbF9kZiwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWp1Y19hc2V4dWFsX21hcmdpbmFsaXR5X2RmLmNzdiIpKQoKCmFqdWNfc2V4dWFsX2RmIDwtIGFqdWNfc2V4dWFsX2VuZmEkbGkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBiaW5kX2NvbHMocHIgPSBhanVjX3NleHVhbF9lbmZhJHByKQoKcmVhZHI6OndyaXRlX2NzdihhanVjX3NleHVhbF9kZiwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWp1Y19zZXh1YWxfbWFyZ2luYWxpdHlfZGYuY3N2IikpCgojYXNleHVhbAphanVjX2VuZmFfc3BlY19hc2V4dWFsIDwtIGVuZmFfaGV4X3Bsb3QoYWp1Y19hc2V4dWFsX2RmLCBtYXJnID0gTWFyLCBzcGVjID0gU3BlMSwgcmVwcm9fbW9kZSA9ICJBc2V4dWFsIikKCmdnc2F2ZSgiYWp1Y19lbmZhX3NwZWNfYXNleHVhbC5wbmciLAogICAgICAgcGxvdCA9IGFqdWNfZW5mYV9zcGVjX2FzZXh1YWwsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiNzZXh1YWwKYWp1Y19lbmZhX3NwZWNfc2V4dWFsIDwtIGVuZmFfaGV4X3Bsb3QoYWp1Y19zZXh1YWxfZGYsIG1hcmcgPSBNYXIsIHNwZWMgPSBTcGUxLCByZXByb19tb2RlID0gIlNleHVhbCIpCgpnZ3NhdmUoImFqdWNfZW5mYV9zcGVjX3NleHVhbC5wbmciLAogICAgICAgcGxvdCA9IGFqdWNfZW5mYV9zcGVjX3NleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKIyMjIDIpIEVORkEgaGlzdG9ncmFtCiNhc2V4dWFsCmhpc3QoYWp1Y19hc2V4dWFsX2VuZmEpCnRpdGxlKG1haW4gPSAiQXNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJhanVjX2FzZXh1YWxfZW5mYV9oaXN0LnBuZyIpKQpoaXN0KGFqdWNfYXNleHVhbF9lbmZhKQp0aXRsZShtYWluID0gIkFzZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKIyBzZXh1YWwKaGlzdChhanVjX3NleHVhbF9lbmZhKQp0aXRsZShtYWluID0gIlNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJhanVjX3NleHVhbF9lbmZhX2hpc3QucG5nIikpCmhpc3QoYWp1Y19zZXh1YWxfZW5mYSkKdGl0bGUobWFpbiA9ICJTZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKIyMjIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlCmFqdWNfdG90YWxfcGNhIDwtIHRvdGFsX2NsaW1hdGVfcGNhX3Bsb3QoYmdfZW52ID0gYWp1Y19iZ19lbnYsIGxvY3MgPSBhc3RlX2xvYywgZ2VudXMgPSAiQXN0ZWxpb3BoYXNtYSIsIHNwZWNpZXMgPSAianVjdW5kdW0iKQoKYWp1Y190b3RhbF9wY2EKCmdnc2F2ZSgiYWp1Y190b3RhbF9wY2EucG5nIiwKICAgICAgIHBsb3QgPSBhanVjX3RvdGFsX3BjYSwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQpgYGAKCgpUcnlpbmcgb3V0IGEgcmVwZWF0IG9mIHRoZSBhbmFseXNlcyB3aXRoIHJlZHVjZWQgZW52aXJvbm1lbnRhbCBzcGFjZS4KUHJpb3JpdGl6aW5nIHZhcmlhYmxlcyB0aGF0IHdpbGwgbGltaXQgdGhlaXIgZGlzdHJpYnV0aW9uIChpLmUuIHZhcmlhYmxlcyB0aGF0IHJlcHJlc2VudCB0aGUgZXh0cmVtZXMpLiBBZnRlciBjb3JyZWxhdGlvbiBhbmFseXNpcywgd2UncmUgbGVmdCB3aXRoIEJJTzUsIEJJTzYsIEJJTzE0LCBCSU8xNy4KYGBge3J9CiMgUENBIG9mIGJhY2tncm91bmQgZS1zcGFjZS4gUmVzdWx0aW5nIGxpc3QgaXMgYSBjb3JyZWxhdGlvbiBoZWF0bWFwIChjb3JfaGVhdG1hcCksIGEgdGliYmxlIG9mIHRoZSByYXN0ZXJzIHdpdGggY29ycmVsYXRpb24gPiB0aGUgY3V0b2ZmIChkZWZhdWx0IGlzIDAuNzUpLCBhbmQgYSB0aWJibGUgb2YgYWxsIHBhaXJ3aXNlIGNvcnJlbGF0aW9ucwphanVjX3BjYSA8LSByYXN0ZXJfY29ycmVsYXRpb24ocmFzdGVyX3N0YWNrID0gYWp1Y19iZ19lbnYpCmFqdWNfcGNhJGNvcl9oZWF0bWFwCmFqdWNfcGNhJHRvcF9jb3IgJT4lIGtuaXRyOjprYWJsZSgpCgpnZ3NhdmUoImFqdWNfcGNhX2NvcnIucG5nIiwKICAgICAgIHBsb3QgPSBhanVjX3BjYSRjb3JfaGVhdG1hcCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKIyB3cml0ZSBjb3JyZWxhdGlvbiBkYXRhIGZyYW1lIHRvIGZpbGUKcmVhZHI6OndyaXRlX2NzdihhanVjX3BjYSR0b3BfY29yLCBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJhanVjX3RvcF9jb3IuY3N2IikpCgpgYGAKCgpSZXBlYXQgdGhlIGFuYWx5c2lzIHdpdGggdGhlIHJlZHVjZWQgZGF0YSBzZXQuCmBgYHtyfQp3X2FqdWMgPC0gcmFzdGVyOjpzdWJzZXQodywgYygiYmlvNSIsICJiaW82IiwgImJpbzE0IiwgImJpbzE3IikpCgojZ2V0IGJhY2tncm91bmQgZW52J3QgZm9yIHRoZSBzcGVjaWVzCmFqdWNfYmdfZW52X3N1YnNldCA8LSBiZ19lbnZfY3JvcChhc3RlX2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXMgPSAianVjdW5kdW0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICBlbnZpcm9ubWVudCA9IHdfYWp1YywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciA9IDAuNSkKCiNlbmZhIGZvciB0aGUgc2V4dWFsIHNwZWNpZXMKYWp1Y19zZXh1YWxfZW5mYV9zdWJzZXQgPC0gZW5mYV9jYWxjX2Z1bihsb2NzID0gYXN0ZV9sb2MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJqdWN1bmR1bSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXNrX3Jhc3RlciA9IGFqdWNfYmdfZW52X3N1YnNldCkKCiNlbmZhIGZvciB0aGUgYXNleHVhbCBzcGVjaWVzCmFqdWNfYXNleHVhbF9lbmZhX3N1YnNldCA8LSBlbmZhX2NhbGNfZnVuKGxvY3MgPSBhc3RlX2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJqdWN1bmR1bSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXNrX3Jhc3RlciA9IGFqdWNfYmdfZW52X3N1YnNldCkKCiMgd3JpdGUgbWFyZ2luYWxpdHkgc2NvcmVzIHRvIGNzdgpyZWFkcjo6d3JpdGVfY3N2KAogIGFqdWNfYXNleHVhbF9lbmZhX3N1YnNldCRtICU+JSBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJtYXJnaW5hbGl0eSIpLAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImFqdWNfc3Vic2V0X2FzZXh1YWxfbWFyZ2luYWxpdHlfc2NvcmUuY3N2IikKKQoKcmVhZHI6OndyaXRlX2NzdigKICBhanVjX3NleHVhbF9lbmZhX3N1YnNldCRtICU+JSBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJtYXJnaW5hbGl0eSIpLAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImFqdWNfc3Vic2V0X3NleHVhbF9tYXJnaW5hbGl0eV9zY29yZS5jc3YiKQopCgojIHBsb3QgdGhlIG1hcmdpbmFsaXR5IHNjb3JlcwphanVjX3N1YnNldF9tYXJnaW5hbGl0eSA8LQogIG1hcmdpbmFsaXR5X2xvbGxpcG9wKAogICAgc2V4X21hcmcgPSBhanVjX3NleHVhbF9lbmZhX3N1YnNldCRtLAogICAgYXNleF9tYXJnID0gYWp1Y19hc2V4dWFsX2VuZmFfc3Vic2V0JG0sCiAgICBmdWxsX3NwZWNpZXNfbmFtZSA9ICJBc3RlbGlhcGhhc21hIGp1Y3VuZHVtIgogICkKCmFqdWNfc3Vic2V0X21hcmdpbmFsaXR5CgpnZ3NhdmUoImFqdWNfc3Vic2V0X21hcmdpbmFsaXR5LnBuZyIsCiAgICAgICBwbG90ID0gYWp1Y19zdWJzZXRfbWFyZ2luYWxpdHksCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCgoKYGBgCgoKVmlzdWFsaXplIHdpdGggdGhlIHJlZHVjZWQgZGF0YSBzZXQuCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMjIyAxKSBFTkZBIHNjYXR0ZXJwbG90CiMgYWNjZXNzIHRoZSByZWxldmFudCB2YWx1ZXMgZm9yIHBsb3R0aW5nCmFqdWNfYXNleHVhbF9kZl9zdWJzZXQgPC0gYWp1Y19hc2V4dWFsX2VuZmFfc3Vic2V0JGxpICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgYmluZF9jb2xzKHByID0gYWp1Y19hc2V4dWFsX2VuZmFfc3Vic2V0JHByKQoKcmVhZHI6OndyaXRlX2NzdigKICBhanVjX2FzZXh1YWxfZGZfc3Vic2V0LAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImFqdWNfYXNleHVhbF9kZl9zdWJzZXQuY3N2IikKKQoKCmFqdWNfc2V4dWFsX2RmX3N1YnNldCA8LSBhanVjX3NleHVhbF9lbmZhX3N1YnNldCRsaSAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGJpbmRfY29scyhwciA9IGFqdWNfc2V4dWFsX2VuZmFfc3Vic2V0JHByKQoKcmVhZHI6OndyaXRlX2NzdigKICBhanVjX3NleHVhbF9kZl9zdWJzZXQsCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWp1Y19zZXh1YWxfZGZfc3Vic2V0LmNzdiIpCikKCiMgYXNleHVhbAphanVjX3N1YnNldF9lbmZhX3NwZWNfYXNleHVhbCA8LSBlbmZhX2hleF9wbG90KGFqdWNfYXNleHVhbF9kZl9zdWJzZXQsIG1hcmcgPSBNYXIsIHNwZWMgPSBTcGUxLCByZXByb19tb2RlID0gIkFzZXh1YWwiKQoKZ2dzYXZlKCJhanVjX3N1YnNldF9lbmZhX3NwZWNfYXNleHVhbC5wbmciLAogICAgICAgcGxvdCA9IGFqdWNfc3Vic2V0X2VuZmFfc3BlY19hc2V4dWFsLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgojIHNleHVhbAphanVjX3N1YnNldF9lbmZhX3NwZWNfc2V4dWFsIDwtIGVuZmFfaGV4X3Bsb3QoYWp1Y19zZXh1YWxfZGZfc3Vic2V0LCBtYXJnID0gTWFyLCBzcGVjID0gU3BlMSwgcmVwcm9fbW9kZSA9ICJTZXh1YWwiKQoKZ2dzYXZlKCJhanVjX3N1YnNldF9lbmZhX3NwZWNfc2V4dWFsLnBuZyIsCiAgICAgICBwbG90ID0gYWp1Y19zdWJzZXRfZW5mYV9zcGVjX3NleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKIyMjIDIpIEVORkEgaGlzdG9ncmFtCiMgYXNleHVhbApoaXN0KGFqdWNfYXNleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJBc2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQoKcG5nKGZpbGVuYW1lID0gZmlsZS5wYXRoKHBsb3RfcGF0aCwgImFqdWNfc3Vic2V0X2FzZXh1YWxfZW5mYV9oaXN0LnBuZyIpKQpoaXN0KGFqdWNfYXNleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJBc2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQpkZXYub2ZmKCkKCgojIHNleHVhbApoaXN0KGFqdWNfc2V4dWFsX2VuZmFfc3Vic2V0KQp0aXRsZShtYWluID0gIlNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJhanVjX3N1YnNldF9zZXh1YWxfZW5mYV9oaXN0LnBuZyIpKQpoaXN0KGFqdWNfc2V4dWFsX2VuZmFfc3Vic2V0KQp0aXRsZShtYWluID0gIlNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKZGV2Lm9mZigpCgojIyMgMykgUENBIG9mIHRvdGFsIGUtc3BhY2UKYWp1Y19zdWJzZXRfdG90YWxfcGNhIDwtIHRvdGFsX2NsaW1hdGVfcGNhX3Bsb3QoYmdfZW52ID0gYWp1Y19iZ19lbnZfc3Vic2V0LCBsb2NzID0gYXN0ZV9sb2MsIGdlbnVzID0gIkFzdGVsaWFwaGFzbWEiLCBzcGVjaWVzID0gImp1Y3VuZHVtIikKCmdnc2F2ZSgiYWp1Y19zdWJzZXRfdG90YWxfcGNhLnBuZyIsCiAgICAgICBwbG90ID0gYWp1Y19zdWJzZXRfdG90YWxfcGNhLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgojIHNhdmUgZW5mYSBvYmplY3RzIGFuZCByZW1vdmUgdGhlbSBmcm9tIHRoZSBlbnZpcm9ubWVudC4gVGhleSB0YWtlIHVwIGEgbG90IG9mIG1lbW9yeS4Kc2F2ZVJEUyhhanVjX3NleHVhbF9lbmZhLCBmaWxlID0gZmlsZS5wYXRoKG9ial9wYXRoLCAiYWp1Y19zZXh1YWxfZW5mYS5SRFMiKSkKcm0oYWp1Y19zZXh1YWxfZW5mYSkKCnNhdmVSRFMoYWp1Y19hc2V4dWFsX2VuZmEsIGZpbGUgPSBmaWxlLnBhdGgob2JqX3BhdGgsICJhanVjX2FzZXh1YWxfZW5mYS5SRFMiKSkKcm0oYWp1Y19hc2V4dWFsX2VuZmEpCgpzYXZlUkRTKGFqdWNfc2V4dWFsX2VuZmFfc3Vic2V0LAogICAgICAgIGZpbGUgPSBmaWxlLnBhdGgob2JqX3BhdGgsICJhanVjX3N1YnNldF9zZXh1YWxfZW5mYS5SRFMiKSkKcm0oYWp1Y19zZXh1YWxfZW5mYV9zdWJzZXQpCgpzYXZlUkRTKGFqdWNfYXNleHVhbF9lbmZhX3N1YnNldCwKICAgICAgICBmaWxlID0gZmlsZS5wYXRoKG9ial9wYXRoLCAiYWp1Y19zdWJzZXRfYXNleHVhbF9lbmZhLlJEUyIpKQpybShhanVjX2FzZXh1YWxfZW5mYV9zdWJzZXQpCmBgYAoKCgoKV2UncmUgYWxzbyBpbnRlcmVzdGVkIGluIHNlZWluZyBpZiBhc2V4dWFsIHBvcHVsYXRpb25zIGxpdmUgaW4gbW9yZSB1bnN0YWJsZSBjbGltYXRpYyBhcmVhcyByZWxhdGl2ZSB0byBzZXh1YWwgcG9wdWxhdGlvbnMuIApgYGB7cn0KYXN0ZV9sb2NzX2FzZXh1YWwgPC0gYXN0ZV9sb2MgJT4lIAogIG11dGF0ZShsYXRfbG9uZyA9IHN0cl9jKGxhdGl0dWRlLCBsb25naXR1ZGUsIHNlcCA9ICJfIikpICU+JSAKICBmaWx0ZXIocmVwcm9kdWN0aXZlX21vZGUgPT0gImFzZXh1YWwiLAogICAgICAgICAhZHVwbGljYXRlZChsYXRfbG9uZykpICU+JSAKICBkcGx5cjo6c2VsZWN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUpCgphc3RlX2xvY3Nfc2V4dWFsIDwtIGFzdGVfbG9jICU+JSAKICBtdXRhdGUobGF0X2xvbmcgPSBzdHJfYyhsYXRpdHVkZSwgbG9uZ2l0dWRlLCBzZXAgPSAiXyIpKSAlPiUgCiAgZmlsdGVyKHJlcHJvZHVjdGl2ZV9tb2RlID09ICJzZXh1YWwiLAogICAgICAgICAhZHVwbGljYXRlZChsYXRfbG9uZykpICU+JSAKICBkcGx5cjo6c2VsZWN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUpCgpwcmVjaXBfYXNleHVhbF9hanVjIDwtIHJhc3Rlcjo6ZXh0cmFjdChwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCwgYXN0ZV9sb2NzX2FzZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIpCgpwcmVjaXBfc2V4dWFsX2FqdWMgPC0gcmFzdGVyOjpleHRyYWN0KHByZWNpcF9zdGFiaWxpdHlfc2NhbGVkLCBhc3RlX2xvY3Nfc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAicHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgpwcmVjaXBfZGZfYWp1YyA8LSBiaW5kX3Jvd3MocHJlY2lwX2FzZXh1YWxfYWp1YywgcHJlY2lwX3NleHVhbF9hanVjKQoKcmVhZHI6OndyaXRlX2NzdihwcmVjaXBfZGZfYWp1YywgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiYWp1Y19wcmVjaXBfc3RhYmlsaXR5X2RmLmNzdiIpKQoKYWp1Y19wcmVjaXBfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBwcmVjaXBfZGZfYWp1YywgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IHByZWNpcF9zdGFiaWxpdHlfc2NhbGVkLCBjb2xvciA9IHJlcHJvZHVjdGl2ZV9tb2RlKSkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuNSwgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gInRyYW5zcGFyZW50IikgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBhbHBoYSA9IDAuNikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAibWFnbWEiKSArCiAgdGhlbWVfZGFyaygpCgpnZ3NhdmUoImFqdWNfcHJlY2lwX3N0YWJpbGl0eS5wbmciLAogICAgICAgcGxvdCA9IGFqdWNfcHJlY2lwX3N0YWJpbGl0eV9wbG90LAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgp0ZW1wX2FzZXh1YWxfYWp1YyA8LSByYXN0ZXI6OmV4dHJhY3QodGVtcF9zdGFiaWxpdHlfc2NhbGVkLCBhc3RlX2xvY3NfYXNleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInRlbXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIpCgp0ZW1wX3NleHVhbF9hanVjIDwtIHJhc3Rlcjo6ZXh0cmFjdCh0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIGFzdGVfbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJ0ZW1wX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgp0ZW1wX2RmX2FqdWMgPC0gYmluZF9yb3dzKHRlbXBfYXNleHVhbF9hanVjLCB0ZW1wX3NleHVhbF9hanVjKQoKcmVhZHI6OndyaXRlX2Nzdih0ZW1wX2RmX2FqdWMsIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImFqdWNfdGVtcF9zdGFiaWxpdHlfZGYuY3N2IikpCgphanVjX3RlbXBfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSB0ZW1wX2RmX2FqdWMsIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSB0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIGNvbG9yID0gcmVwcm9kdWN0aXZlX21vZGUpKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC41LCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFscGhhID0gMC42KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCmdnc2F2ZSgiYWp1Y19wcmVjaXBfc3RhYmlsaXR5LnBuZyIsCiAgICAgICBwbG90ID0gYWp1Y190ZW1wX3N0YWJpbGl0eV9wbG90LAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgpvdmVyYWxsX2FzZXh1YWxfYWp1YyA8LSByYXN0ZXI6OmV4dHJhY3Qob3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkLCBhc3RlX2xvY3NfYXNleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIpCgpvdmVyYWxsX3NleHVhbF9hanVjIDwtIHJhc3Rlcjo6ZXh0cmFjdChvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQsIGFzdGVfbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgpvdmVyYWxsX2RmX2FqdWMgPC0gYmluZF9yb3dzKG92ZXJhbGxfYXNleHVhbF9hanVjLCBvdmVyYWxsX3NleHVhbF9hanVjKQoKcmVhZHI6OndyaXRlX2NzdihvdmVyYWxsX2RmX2FqdWMsIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImFqdWNfb3ZlcmFsbF9zdGFiaWxpdHlfZGYuY3N2IikpCgphanVjX292ZXJhbGxfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBvdmVyYWxsX2RmX2FqdWMsIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSBvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQsIGNvbG9yID0gcmVwcm9kdWN0aXZlX21vZGUpKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC41LCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFscGhhID0gMC42KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCmdnc2F2ZSgiYWp1Y19vdmVyYWxsX3N0YWJpbGl0eS5wbmciLAogICAgICAgcGxvdCA9IGFqdWNfb3ZlcmFsbF9zdGFiaWxpdHlfcGxvdCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKYGBgCgpQdXQgYWxsIG91dHB1dCBpbnRvIHNwZWNpZXMtc3BlY2lmaWMgc3ViZm9sZGVycy4KYGBge3IgcmVzdWx0cz0iaGlkZSJ9CmFqdWNfb3V0X2ludF9wYXRoIDwtIGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCAiYXN0ZWxpYXBoYXNtYV9qdWN1bmR1bSIpCmFqdWNfb3V0X3Bsb3RfcGF0aCA8LSBmaWxlLnBhdGgocGxvdF9wYXRoLCAiYXN0ZWxpYXBoYXNtYV9qdWN1bmR1bSIpCmFqdWNfb3V0X3NwcmVhZF9wYXRoIDwtIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImFzdGVsaWFwaGFzbWFfanVjdW5kdW0iKQphanVjX291dF9vYmpfcGF0aCA8LSBmaWxlLnBhdGgob2JqX3BhdGgsICJhc3RlbGlhcGhhc21hX2p1Y3VuZHVtIikKCiMgbW92ZSBpbnRlcmFjdGl2ZQptb3ZlX3RvX3NwZWNpZXMoaW5fcGF0aCA9IGludGVyYWN0aXZlX3BhdGgsCiAgICAgICAgICAgICAgICBvdXRfcGF0aCA9IGFqdWNfb3V0X2ludF9wYXRoLAogICAgICAgICAgICAgICAgcGF0dGVybiA9ICJhanVjIikKIyBtb3ZlIHBsb3RzCm1vdmVfdG9fc3BlY2llcyhpbl9wYXRoID0gcGxvdF9wYXRoLAogICAgICAgICAgICAgICAgb3V0X3BhdGggPSBhanVjX291dF9wbG90X3BhdGgsCiAgICAgICAgICAgICAgICBwYXR0ZXJuID0gImFqdWMiKQoKIyBtb3ZlIHNwcmVhZHNoZWV0cwptb3ZlX3RvX3NwZWNpZXMoaW5fcGF0aCA9IHNwcmVhZF9wYXRoLAogICAgICAgICAgICAgICAgb3V0X3BhdGggPSBhanVjX291dF9zcHJlYWRfcGF0aCwKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAiYWp1YyIpCgojIG1vdmUgb2JqZWN0cwptb3ZlX3RvX3NwZWNpZXMoaW5fcGF0aCA9IG9ial9wYXRoLAogICAgICAgICAgICAgICAgb3V0X3BhdGggPSBhanVjX291dF9vYmpfcGF0aCwKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAiYWp1YyIpCmBgYAoKIyMjIENsaXRhcmNodXMKCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CnN1bW1hcnlfbGlzdF9jbGl0YSA8LSBzcGVjaWVzX3BjYV9mdW4obG9jX2NsaW0sICJDbGl0YXJjaHVzIikKY2xpdGFfcGxvdCA8LSBwbG90X2NsaW1fcGNhKHN1bW1hcnlfbGlzdF9jbGl0YSRsb2NfY2xpbSwgc3VtbWFyeV9saXN0X2NsaXRhJHN1bW1hcnlfcGNhLCBmYWN0b3IgPSAicmVwcm9kdWN0aXZlX21vZGUiKQpjbGl0YV9wbG90CgoKaHRtbHdpZGdldHM6OnNhdmVXaWRnZXQoY2xpdGFfcGxvdCwgZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJDbGl0YXJjaHVzX3BjYS5odG1sIiksIHNlbGZjb250YWluZWQgPSBUUlVFKQoKI2ZpbHRlciBsb2NhbGl0aWVzIGZvciB0aGUgZm9jYWwgZ2VudXMKY2xpdGFfbG9jIDwtIGxvYyAlPiUgCiAgZmlsdGVyKGdlbnVzID09ICJDbGl0YXJjaHVzIikKICAKI3VzZSBzb3VyY2VkIHBsb3RfbG9jc19sZWFmbGV0IHNjcmlwdCB0byBwbG90IGxvY2FsaXRpZXMKY2xpdGFfbWFwIDwtIHBsb3RfbG9jc19sZWFmbGV0KGNsaXRhX2xvYywgInJlcHJvZHVjdGl2ZV9tb2RlIikKCmNsaXRhX21hcAoKIyBzYXZlIHRoZSBtYXAKCm1hcHZpZXc6Om1hcHNob3QoCiAgY2xpdGFfbWFwLAogIHVybCA9IGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCAiY2xpdGFfbWFwLmh0bWwiKSwKICBmaWxlID0gcGFzdGUwKGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCAiY2xpdGFfbWFwLnBkZiIpKQopCgpgYGAKCgpgYGB7cn0Kc3VtbWFyeV9saXN0X2NsaXRhJHN1bW1hcnlfcGNhCmxvYWRpbmdzX2NsaXRhIDwtIHN1bW1hcnlfbGlzdF9jbGl0YSRzdW1tYXJ5X3BjYSRyb3RhdGlvbgprbml0cjo6a2FibGUocm91bmQobG9hZGluZ3NfY2xpdGFbLDE6M10sMykpICNUYWJsZSBvZiBsb2FkaW5nIHNjb3JlcyBmb3IgdGhlIGZpcnN0IDMgUENzLiAKYGBgCgoKTm93IEknbSBnb2luZyB0byBwZXJmb3JtIGVudmlyb25tZW50YWwgbmljaGUgZmFjdG9yIGFuYWx5c2lzIHdpdGggc2V4dWFsIGFuZCBhc2V4dWFsIHBvcHVsYXRpb25zIHdpdGhpbiB0aGUgc3BlY2llcy4KYGBge3IgY2FjaGU9VFJVRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KCiNnZXQgYmFja2dyb3VuZCBlbnYndCBmb3IgdGhlIHNwZWNpZXMKY2hvb19iZ19lbnYgPC0gYmdfZW52X2Nyb3AoCiAgY2xpdGFfbG9jLAogIHNwZWNpZXMgPSAiaG9va2VyaSIsCiAgZW52aXJvbm1lbnQgPSB3LAogIGJ1ZmZlciA9IDAuNQopCgojZW5mYSBmb3IgdGhlIHNleHVhbCBzcGVjaWVzCmNob29fc2V4dWFsX2VuZmEgPC0gZW5mYV9jYWxjX2Z1bigKICBsb2NzID0gY2xpdGFfbG9jLAogIHNwZWNpZXMgPSAiaG9va2VyaSIsCiAgcmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIiwKICBtYXNrX3Jhc3RlciA9IGNob29fYmdfZW52CikKCiNlbmZhIGZvciB0aGUgYXNleHVhbCBzcGVjaWVzCmNob29fYXNleHVhbF9lbmZhIDwtIGVuZmFfY2FsY19mdW4oCiAgbG9jcyA9IGNsaXRhX2xvYywKICBzcGVjaWVzID0gImhvb2tlcmkiLAogIHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiLAogIG1hc2tfcmFzdGVyID0gY2hvb19iZ19lbnYKKQoKIyB3cml0ZSBzY29yZXMgdG8gY3N2cwpyZWFkcjo6d3JpdGVfY3N2KAogIGNob29fYXNleHVhbF9lbmZhJG0gJT4lIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm1hcmdpbmFsaXR5IiksCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiY2hvb19hc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgY2hvb19zZXh1YWxfZW5mYSRtICU+JSBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJtYXJnaW5hbGl0eSIpLAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImNob29fc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCiNwbG90IHRoZSBtYXJnaW5hbGl0eSBzY29yZXMKY2hvb19tYXJnaW5hbGl0eSA8LQogIG1hcmdpbmFsaXR5X2xvbGxpcG9wKAogICAgc2V4X21hcmcgPSBjaG9vX3NleHVhbF9lbmZhJG0sCiAgICBhc2V4X21hcmcgPSBjaG9vX2FzZXh1YWxfZW5mYSRtLAogICAgZnVsbF9zcGVjaWVzX25hbWUgPSAiQ2xpdGFyY2h1cyBob29rZXJpIgogICkKCmNob29fbWFyZ2luYWxpdHkKCmdnc2F2ZSgKICAiY2hvb19tYXJnaW5hbGl0eV9sb2xsaXBvcC5wbmciLAogIHBsb3QgPSBjaG9vX21hcmdpbmFsaXR5LAogIGRldmljZSA9ICJwbmciLAogIHBhdGggPSBwbG90X3BhdGgsCiAgZHBpID0gInJldGluYSIKKQpgYGAKCkEgY291cGxlIGRpZmZlcmVudCB3YXlzIHRvIHZpc3VhbGl6ZSB0aGUgZW52aXJvbm1lbnRhbCB2YXJpYXRpb24uIDEpIFNjYXR0ZXJwbG90IHZpc3VhbGl6YXRpb25zIG9mIG1hcmdpbmFsaXR5IHZzIGF4aXMgMSBvZiB0aGUgc3BlY2lhbGl6YXRpb24gd2l0aCB0aGUgbGFiZWxzIHJlbW92ZWQgKHRoZXkgbWFrZSB0aGluZ3MgaW5kaXNjZXJuYWJsZSkuIFJlZCA9IG9jY3VwaWVkIGUtc3BhY2UuIEdyYXkgPSBCYWNrZ3JvdW5kIGUtc3BhY2UuIDIpIEVORkEgaGlzdG9ncmFtIHZpc3VhbGl6YXRpb25zIG9mIG1hcmdpbmFsaXR5IGFuZCBzcGVjaWFsaXphdGlvbiBheGVzLiAzKSBQQ0Egb2YgdG90YWwgZS1zcGFjZSB3aXRoIGNvbG9ycyBjb3JyZXNwb25kaW5nIHRvIHNleHVhbCB2cy4gYXNleHVhbCBwb3B1bGF0aW9ucy4gCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIyMgMSkgRU5GQSBzY2F0dGVycGxvdAojYWNjZXNzIHRoZSByZWxldmFudCB2YWx1ZXMgZm9yIHBsb3R0aW5nCmNob29fYXNleHVhbF9kZiA8LSBjaG9vX2FzZXh1YWxfZW5mYSRsaSAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGJpbmRfY29scyhwciA9IGNob29fYXNleHVhbF9lbmZhJHByKQoKcmVhZHI6OndyaXRlX2NzdihjaG9vX2FzZXh1YWxfZGYsIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImNob29fYXNleHVhbF9tYXJnaW5hbGl0eV9kZi5jc3YiKSkKCmNob29fc2V4dWFsX2RmIDwtIGNob29fc2V4dWFsX2VuZmEkbGkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBiaW5kX2NvbHMocHIgPSBjaG9vX3NleHVhbF9lbmZhJHByKQoKcmVhZHI6OndyaXRlX2NzdihjaG9vX3NleHVhbF9kZiwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiY2hvb19zZXh1YWxfbWFyZ2luYWxpdHlfZGYuY3N2IikpCgojIGFzZXh1YWwKY2hvb19lbmZhX3NwZWNfYXNleHVhbCA8LSBlbmZhX2hleF9wbG90KGNob29fYXNleHVhbF9kZiwgbWFyZyA9IE1hciwgc3BlYyA9IFNwZTEsIHJlcHJvX21vZGUgPSAiQXNleHVhbCIpCgpnZ3NhdmUoImNob29fZW5mYV9zcGVjX2FzZXh1YWwucG5nIiwKICAgICAgIHBsb3QgPSBjaG9vX2VuZmFfc3BlY19hc2V4dWFsLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgojc2V4dWFsCmNob29fZW5mYV9zcGVjX3NleHVhbCA8LSBlbmZhX2hleF9wbG90KGNob29fc2V4dWFsX2RmLCBtYXJnID0gTWFyLCBzcGVjID0gU3BlMSwgcmVwcm9fbW9kZSA9ICJTZXh1YWwiKQoKZ2dzYXZlKCJjaG9vX2VuZmFfc3BlY19zZXh1YWwucG5nIiwKICAgICAgIHBsb3QgPSBjaG9vX2VuZmFfc3BlY19zZXh1YWwsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMjIyAyKSBFTkZBIGhpc3RvZ3JhbQojYXNleHVhbApoaXN0KGNob29fYXNleHVhbF9lbmZhKQp0aXRsZShtYWluID0gIkFzZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCgpwbmcoZmlsZW5hbWUgPSBmaWxlLnBhdGgocGxvdF9wYXRoLCAiY2hvb19hc2V4dWFsX2VuZmFfaGlzdC5wbmciKSkKaGlzdChjaG9vX2FzZXh1YWxfZW5mYSkKdGl0bGUobWFpbiA9ICJBc2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQpkZXYub2ZmKCkKCiNzZXh1YWwKaGlzdChjaG9vX3NleHVhbF9lbmZhKQp0aXRsZShtYWluID0gIlNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJjaG9vX3NleHVhbF9lbmZhX2hpc3QucG5nIikpCmhpc3QoY2hvb19zZXh1YWxfZW5mYSkKdGl0bGUobWFpbiA9ICJTZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKIyMjIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlCmNob29fdG90YWxfcGNhIDwtIHRvdGFsX2NsaW1hdGVfcGNhX3Bsb3QoYmdfZW52ID0gY2hvb19iZ19lbnYsIGxvY3MgPSBjbGl0YV9sb2MsIGdlbnVzID0gIkNsaXRhcmNodXMiLCBzcGVjaWVzID0gImhvb2tlcmkiKQoKY2hvb190b3RhbF9wY2EKCmdnc2F2ZSgiY2hvb190b3RhbF9wY2EucG5nIiwKICAgICAgIHBsb3QgPSBjaG9vX3RvdGFsX3BjYSwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKYGBgCgpUcnlpbmcgb3V0IGEgcmVwZWF0IG9mIHRoZSBhbmFseXNlcyB3aXRoIHJlZHVjZWQgZW52aXJvbm1lbnRhbCBzcGFjZS4KUHJpb3JpdGl6aW5nIHZhcmlhYmxlcyB0aGF0IHdpbGwgbGltaXQgdGhlaXIgZGlzdHJpYnV0aW9uIChpLmUuIHZhcmlhYmxlcyB0aGF0IHJlcHJlc2VudCB0aGUgZXh0cmVtZXMpLiBBZnRlciBjb3JyZWxhdGlvbiBhbmFseXNpcywgd2UncmUgbGVmdCB3aXRoIEJJTzgsIEJJTzExLCBCSU8xNSwgQklPMTcuIApgYGB7cn0KIyBQQ0Egb2YgYmFja2dyb3VuZCBlLXNwYWNlLiBSZXN1bHRpbmcgbGlzdCBpcyBhIGNvcnJlbGF0aW9uIGhlYXRtYXAgKGNvcl9oZWF0bWFwKSwgYSB0aWJibGUgb2YgdGhlIHJhc3RlcnMgd2l0aCBjb3JyZWxhdGlvbiA+IHRoZSBjdXRvZmYgKGRlZmF1bHQgaXMgMC43NSksIGFuZCBhIHRpYmJsZSBvZiBhbGwgcGFpcndpc2UgY29ycmVsYXRpb25zCmNob29fcGNhIDwtIHJhc3Rlcl9jb3JyZWxhdGlvbihyYXN0ZXJfc3RhY2sgPSBjaG9vX2JnX2VudikKY2hvb19wY2EkY29yX2hlYXRtYXAKY2hvb19wY2EkdG9wX2NvciAlPiUga25pdHI6OmthYmxlKCkKCmdnc2F2ZSgiY2hvb19wY2FfY29yci5wbmciLAogICAgICAgcGxvdCA9IGNob29fcGNhJGNvcl9oZWF0bWFwLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgojIHdyaXRlIGNvcnJlbGF0aW9uIGRhdGEgZnJhbWUgdG8gZmlsZQpyZWFkcjo6d3JpdGVfY3N2KGNob29fcGNhJHRvcF9jb3IsIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImNob29fdG9wX2Nvci5jc3YiKSkKCmBgYAoKUmVwZWF0IHRoZSBhbmFseXNpcyB3aXRoIHRoZSByZWR1Y2VkIGRhdGEgc2V0LgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQp3X2Nob28gPC0gcmFzdGVyOjpzdWJzZXQodywgYygiYmlvOCIsICJiaW8xMSIsICJiaW8xNSIsICJiaW8xNyIpKQoKI2dldCBiYWNrZ3JvdW5kIGVudid0IGZvciB0aGUgc3BlY2llcwpjaG9vX2JnX2Vudl9zdWJzZXQgPC0gYmdfZW52X2Nyb3AoY2xpdGFfbG9jLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJob29rZXJpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52aXJvbm1lbnQgPSB3X2Nob28sIAogICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIgPSAwLjUpCgojZW5mYSBmb3IgdGhlIHNleHVhbCBzcGVjaWVzCmNob29fc2V4dWFsX2VuZmFfc3Vic2V0IDwtIGVuZmFfY2FsY19mdW4obG9jcyA9IGNsaXRhX2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzID0gImhvb2tlcmkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFza19yYXN0ZXIgPSBjaG9vX2JnX2Vudl9zdWJzZXQpCgojZW5mYSBmb3IgdGhlIGFzZXh1YWwgc3BlY2llcwpjaG9vX2FzZXh1YWxfZW5mYV9zdWJzZXQgPC0gZW5mYV9jYWxjX2Z1bihsb2NzID0gY2xpdGFfbG9jLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzID0gImhvb2tlcmkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFza19yYXN0ZXIgPSBjaG9vX2JnX2Vudl9zdWJzZXQpCgojIHdyaXRlIG1hcmdpbmFsaXR5IHNjb3JlcyB0byBjc3YKcmVhZHI6OndyaXRlX2NzdigKICBjaG9vX2FzZXh1YWxfZW5mYV9zdWJzZXQkbSAlPiUgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAibWFyZ2luYWxpdHkiKSwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJjaG9vX3N1YnNldF9hc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgY2hvb19zZXh1YWxfZW5mYV9zdWJzZXQkbSAlPiUgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAibWFyZ2luYWxpdHkiKSwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJjaG9vX3N1YnNldF9zZXh1YWxfbWFyZ2luYWxpdHlfc2NvcmUuY3N2IikKKQoKIyBwbG90IHRoZSBtYXJnaW5hbGl0eSBzY29yZXMKY2hvb19zdWJzZXRfbWFyZ2luYWxpdHkgPC0KICBtYXJnaW5hbGl0eV9sb2xsaXBvcCgKICAgIHNleF9tYXJnID0gY2hvb19zZXh1YWxfZW5mYV9zdWJzZXQkbSwKICAgIGFzZXhfbWFyZyA9IGNob29fYXNleHVhbF9lbmZhX3N1YnNldCRtLAogICAgZnVsbF9zcGVjaWVzX25hbWUgPSAiQ2xpdGFyY2h1cyBob29rZXJpIgogICkKCmNob29fc3Vic2V0X21hcmdpbmFsaXR5CgpnZ3NhdmUoImNob29fc3Vic2V0X21hcmdpbmFsaXR5LnBuZyIsCiAgICAgICBwbG90ID0gY2hvb19zdWJzZXRfbWFyZ2luYWxpdHksCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCmBgYAoKClZpc3VhbGl6ZSB3aXRoIHRoZSByZWR1Y2VkIGRhdGEgc2V0LgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojIyMgMSkgRU5GQSBzY2F0dGVycGxvdAojIGFjY2VzcyB0aGUgcmVsZXZhbnQgdmFsdWVzIGZvciBwbG90dGluZwpjaG9vX2FzZXh1YWxfZGZfc3Vic2V0IDwtIGNob29fYXNleHVhbF9lbmZhX3N1YnNldCRsaSAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGJpbmRfY29scyhwciA9IGNob29fYXNleHVhbF9lbmZhX3N1YnNldCRwcikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgY2hvb19hc2V4dWFsX2RmX3N1YnNldCwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJjaG9vX2FzZXh1YWxfZGZfc3Vic2V0LmNzdiIpCikKCgpjaG9vX3NleHVhbF9kZl9zdWJzZXQgPC0gY2hvb19zZXh1YWxfZW5mYV9zdWJzZXQkbGkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBiaW5kX2NvbHMocHIgPSBjaG9vX3NleHVhbF9lbmZhX3N1YnNldCRwcikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgY2hvb19zZXh1YWxfZGZfc3Vic2V0LAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImNob29fc2V4dWFsX2RmX3N1YnNldC5jc3YiKQopCgojIGFzZXh1YWwKY2hvb19zdWJzZXRfZW5mYV9zcGVjX2FzZXh1YWwgPC0gZW5mYV9oZXhfcGxvdChjaG9vX2FzZXh1YWxfZGZfc3Vic2V0LCBtYXJnID0gTWFyLCBzcGVjID0gU3BlMSwgcmVwcm9fbW9kZSA9ICJBc2V4dWFsIikKCmdnc2F2ZSgiY2hvb19zdWJzZXRfZW5mYV9zcGVjX2FzZXh1YWwucG5nIiwKICAgICAgIHBsb3QgPSBjaG9vX3N1YnNldF9lbmZhX3NwZWNfYXNleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKIyBzZXh1YWwKY2hvb19zdWJzZXRfZW5mYV9zcGVjX3NleHVhbCA8LSBlbmZhX2hleF9wbG90KGNob29fc2V4dWFsX2RmX3N1YnNldCwgbWFyZyA9IE1hciwgc3BlYyA9IFNwZTEsIHJlcHJvX21vZGUgPSAiU2V4dWFsIikKCmdnc2F2ZSgiY2hvb19zdWJzZXRfZW5mYV9zcGVjX3NleHVhbC5wbmciLAogICAgICAgcGxvdCA9IGNob29fc3Vic2V0X2VuZmFfc3BlY19zZXh1YWwsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMjIyAyKSBFTkZBIGhpc3RvZ3JhbQojIGFzZXh1YWwKaGlzdChjaG9vX2FzZXh1YWxfZW5mYV9zdWJzZXQpCnRpdGxlKG1haW4gPSAiQXNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJjaG9vX3N1YnNldF9hc2V4dWFsX2VuZmFfaGlzdC5wbmciKSkKaGlzdChjaG9vX2FzZXh1YWxfZW5mYV9zdWJzZXQpCnRpdGxlKG1haW4gPSAiQXNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKZGV2Lm9mZigpCgoKIyBzZXh1YWwKaGlzdChjaG9vX3NleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJTZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCgpwbmcoZmlsZW5hbWUgPSBmaWxlLnBhdGgocGxvdF9wYXRoLCAiY2hvb19zdWJzZXRfc2V4dWFsX2VuZmFfaGlzdC5wbmciKSkKaGlzdChjaG9vX3NleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJTZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKIyMjIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlCmNob29fc3Vic2V0X3RvdGFsX3BjYSA8LSB0b3RhbF9jbGltYXRlX3BjYV9wbG90KGJnX2VudiA9IGNob29fYmdfZW52X3N1YnNldCwgbG9jcyA9IGNsaXRhX2xvYywgZ2VudXMgPSAiQ2xpdGFyY2h1cyIsIHNwZWNpZXMgPSAiaG9va2VyaSIpCgpjaG9vX3N1YnNldF90b3RhbF9wY2EKCmdnc2F2ZSgiY2hvb19zdWJzZXRfdG90YWxfcGNhLnBuZyIsCiAgICAgICBwbG90ID0gY2hvb19zdWJzZXRfdG90YWxfcGNhLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgojIHNhdmUgZW5mYSBvYmplY3RzIGFuZCByZW1vdmUgdGhlbSBmcm9tIHRoZSBlbnZpcm9ubWVudC4gVGhleSB0YWtlIHVwIGEgbG90IG9mIG1lbW9yeS4Kc2F2ZVJEUyhjaG9vX3NleHVhbF9lbmZhLCBmaWxlID0gZmlsZS5wYXRoKG9ial9wYXRoLCAiY2hvb19zZXh1YWxfZW5mYS5SRFMiKSkKcm0oY2hvb19zZXh1YWxfZW5mYSkKCnNhdmVSRFMoY2hvb19hc2V4dWFsX2VuZmEsIGZpbGUgPSBmaWxlLnBhdGgob2JqX3BhdGgsICJjaG9vX2FzZXh1YWxfZW5mYS5SRFMiKSkKcm0oY2hvb19hc2V4dWFsX2VuZmEpCgpzYXZlUkRTKGNob29fc2V4dWFsX2VuZmFfc3Vic2V0LAogICAgICAgIGZpbGUgPSBmaWxlLnBhdGgob2JqX3BhdGgsICJjaG9vX3N1YnNldF9zZXh1YWxfZW5mYS5SRFMiKSkKcm0oY2hvb19zZXh1YWxfZW5mYV9zdWJzZXQpCgpzYXZlUkRTKGNob29fYXNleHVhbF9lbmZhX3N1YnNldCwKICAgICAgICBmaWxlID0gZmlsZS5wYXRoKG9ial9wYXRoLCAiY2hvb19zdWJzZXRfYXNleHVhbF9lbmZhLlJEUyIpKQpybShjaG9vX2FzZXh1YWxfZW5mYV9zdWJzZXQpCmBgYAoKCldlJ3JlIGFsc28gaW50ZXJlc3RlZCBpbiBzZWVpbmcgaWYgYXNleHVhbCBwb3B1bGF0aW9ucyBsaXZlIGluIG1vcmUgdW5zdGFibGUgY2xpbWF0aWMgYXJlYXMgcmVsYXRpdmUgdG8gc2V4dWFsIHBvcHVsYXRpb25zLiAKYGBge3Igd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KY2xpdGFfbG9jc19hc2V4dWFsIDwtIGNsaXRhX2xvYyAlPiUgCiAgbXV0YXRlKGxhdF9sb25nID0gc3RyX2MobGF0aXR1ZGUsIGxvbmdpdHVkZSwgc2VwID0gIl8iKSkgJT4lIAogIGZpbHRlcihyZXByb2R1Y3RpdmVfbW9kZSA9PSAiYXNleHVhbCIsCiAgICAgICAgICFkdXBsaWNhdGVkKGxhdF9sb25nKSkgJT4lIAogIGRwbHlyOjpzZWxlY3QobG9uZ2l0dWRlLCBsYXRpdHVkZSkKCmNsaXRhX2xvY3Nfc2V4dWFsIDwtIGNsaXRhX2xvYyAlPiUgCiAgbXV0YXRlKGxhdF9sb25nID0gc3RyX2MobGF0aXR1ZGUsIGxvbmdpdHVkZSwgc2VwID0gIl8iKSkgJT4lIAogIGZpbHRlcihyZXByb2R1Y3RpdmVfbW9kZSA9PSAic2V4dWFsIiwKICAgICAgICAgIWR1cGxpY2F0ZWQobGF0X2xvbmcpKSAlPiUgCiAgZHBseXI6OnNlbGVjdChsb25naXR1ZGUsIGxhdGl0dWRlKQoKcHJlY2lwX2FzZXh1YWxfY2hvbyA8LSByYXN0ZXI6OmV4dHJhY3QocHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQsIGNsaXRhX2xvY3NfYXNleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInByZWNpcF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCnByZWNpcF9zZXh1YWxfY2hvbyA8LSByYXN0ZXI6OmV4dHJhY3QocHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQsIGNsaXRhX2xvY3Nfc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAicHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgpwcmVjaXBfZGZfY2hvbyA8LSBiaW5kX3Jvd3MocHJlY2lwX2FzZXh1YWxfY2hvbywgcHJlY2lwX3NleHVhbF9jaG9vKQoKcmVhZHI6OndyaXRlX2NzdihwcmVjaXBfZGZfY2hvbywgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAiY2hvb19wcmVjaXBfc3RhYmlsaXR5X2RmLmNzdiIpKQoKY2hvb19wcmVjaXBfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBwcmVjaXBfZGZfY2hvbywgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IHByZWNpcF9zdGFiaWxpdHlfc2NhbGVkLCBjb2xvciA9IHJlcHJvZHVjdGl2ZV9tb2RlKSkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuNSwgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gInRyYW5zcGFyZW50IikgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBhbHBoYSA9IDAuNikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAibWFnbWEiKSArCiAgdGhlbWVfZGFyaygpCgpjaG9vX3ByZWNpcF9zdGFiaWxpdHlfcGxvdAoKZ2dzYXZlKCJjaG9vX3ByZWNpcF9zdGFiaWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSBjaG9vX3ByZWNpcF9zdGFiaWxpdHlfcGxvdCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKdGVtcF9hc2V4dWFsX2Nob28gPC0gcmFzdGVyOjpleHRyYWN0KHRlbXBfc3RhYmlsaXR5X3NjYWxlZCwgY2xpdGFfbG9jc19hc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAidGVtcF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCnRlbXBfc2V4dWFsX2Nob28gPC0gcmFzdGVyOjpleHRyYWN0KHRlbXBfc3RhYmlsaXR5X3NjYWxlZCwgY2xpdGFfbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJ0ZW1wX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgp0ZW1wX2RmX2Nob28gPC0gYmluZF9yb3dzKHRlbXBfYXNleHVhbF9jaG9vLCB0ZW1wX3NleHVhbF9jaG9vKQoKcmVhZHI6OndyaXRlX2Nzdih0ZW1wX2RmX2Nob28sIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImNob29fdGVtcF9zdGFiaWxpdHlfZGYuY3N2IikpCgpjaG9vX3RlbXBfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSB0ZW1wX2RmX2Nob28sIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSB0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIGNvbG9yID0gcmVwcm9kdWN0aXZlX21vZGUpKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC41LCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFscGhhID0gMC42KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCmNob29fdGVtcF9zdGFiaWxpdHlfcGxvdAoKZ2dzYXZlKCJjaG9vX3ByZWNpcF9zdGFiaWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSBjaG9vX3RlbXBfc3RhYmlsaXR5X3Bsb3QsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCm92ZXJhbGxfYXNleHVhbF9jaG9vIDwtIHJhc3Rlcjo6ZXh0cmFjdChvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQsIGNsaXRhX2xvY3NfYXNleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIpCgpvdmVyYWxsX3NleHVhbF9jaG9vIDwtIHJhc3Rlcjo6ZXh0cmFjdChvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQsIGNsaXRhX2xvY3Nfc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAib3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiKQoKb3ZlcmFsbF9kZl9jaG9vIDwtIGJpbmRfcm93cyhvdmVyYWxsX2FzZXh1YWxfY2hvbywgb3ZlcmFsbF9zZXh1YWxfY2hvbykKCnJlYWRyOjp3cml0ZV9jc3Yob3ZlcmFsbF9kZl9jaG9vLCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJjaG9vX292ZXJhbGxfc3RhYmlsaXR5X2RmLmNzdiIpKQoKY2hvb19vdmVyYWxsX3N0YWJpbGl0eV9wbG90IDwtIGdncGxvdChkYXRhID0gb3ZlcmFsbF9kZl9jaG9vLCBhZXMoeCA9IHJlcHJvZHVjdGl2ZV9tb2RlLCB5ID0gb3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkLCBjb2xvciA9IHJlcHJvZHVjdGl2ZV9tb2RlKSkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuNSwgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gInRyYW5zcGFyZW50IikgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBhbHBoYSA9IDAuNikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAibWFnbWEiKSArCiAgdGhlbWVfZGFyaygpCgpjaG9vX292ZXJhbGxfc3RhYmlsaXR5X3Bsb3QKCmdnc2F2ZSgiY2hvb19vdmVyYWxsX3N0YWJpbGl0eS5wbmciLAogICAgICAgcGxvdCA9IGNob29fb3ZlcmFsbF9zdGFiaWxpdHlfcGxvdCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQpgYGAKClB1dCBhbGwgb3V0cHV0IGludG8gc3BlY2llcy1zcGVjaWZpYyBzdWJmb2xkZXJzLgpgYGB7ciByZXN1bHRzPSJoaWRlIn0KY2hvb19vdXRfaW50X3BhdGggPC0gZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJjbGl0YXJjaHVzX2hvb2tlcmkiKQpjaG9vX291dF9wbG90X3BhdGggPC0gZmlsZS5wYXRoKHBsb3RfcGF0aCwgImNsaXRhcmNodXNfaG9va2VyaSIpCmNob29fb3V0X3NwcmVhZF9wYXRoIDwtIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgImNsaXRhcmNodXNfaG9va2VyaSIpCmNob29fb3V0X29ial9wYXRoIDwtIGZpbGUucGF0aChvYmpfcGF0aCwgImNsaXRhcmNodXNfaG9va2VyaSIpCgojIG1vdmUgaW50ZXJhY3RpdmUKbW92ZV90b19zcGVjaWVzKGluX3BhdGggPSBpbnRlcmFjdGl2ZV9wYXRoLAogICAgICAgICAgICAgICAgb3V0X3BhdGggPSBjaG9vX291dF9pbnRfcGF0aCwKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAiY2hvbyIpCiMgbW92ZSBwbG90cwptb3ZlX3RvX3NwZWNpZXMoaW5fcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgICAgICAgICAgIG91dF9wYXRoID0gY2hvb19vdXRfcGxvdF9wYXRoLAogICAgICAgICAgICAgICAgcGF0dGVybiA9ICJjaG9vIikKCiMgbW92ZSBzcHJlYWRzaGVldHMKbW92ZV90b19zcGVjaWVzKGluX3BhdGggPSBzcHJlYWRfcGF0aCwKICAgICAgICAgICAgICAgIG91dF9wYXRoID0gY2hvb19vdXRfc3ByZWFkX3BhdGgsCiAgICAgICAgICAgICAgICBwYXR0ZXJuID0gImNob28iKQoKIyBtb3ZlIG9iamVjdHMKbW92ZV90b19zcGVjaWVzKGluX3BhdGggPSBvYmpfcGF0aCwKICAgICAgICAgICAgICAgIG91dF9wYXRoID0gY2hvb19vdXRfb2JqX3BhdGgsCiAgICAgICAgICAgICAgICBwYXR0ZXJuID0gImNob28iKQpgYGAKCiMjIyBNaWNyYXJjaHVzCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CnN1bW1hcnlfbGlzdF9taWNyYSA8LSBzcGVjaWVzX3BjYV9mdW4obG9jX2NsaW0sICJtaWNyYXJjaHVzIikKbWljcmFfcGxvdCA8LSBwbG90X2NsaW1fcGNhKHN1bW1hcnlfbGlzdF9taWNyYSRsb2NfY2xpbSwgc3VtbWFyeV9saXN0X21pY3JhJHN1bW1hcnlfcGNhLCBmYWN0b3IgPSAicmVwcm9kdWN0aXZlX21vZGUiKQptaWNyYV9wbG90CgojIGlmIHNlbGZjb250YWluZWQgPSBUUlVFLCB5b3UgY2FuIHJlbW92ZSB0aGUgZm9sZGVyIHRoYXQgZ2V0cyBhZGRlZCBhbG9uZ3NpZGUgdGhlIHBsb3QuCmh0bWx3aWRnZXRzOjpzYXZlV2lkZ2V0KG1pY3JhX3Bsb3QsCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCAibWljcmFyY2h1c19wY2EuaHRtbCIpLAogICAgICAgICAgICAgICAgICAgICAgICBzZWxmY29udGFpbmVkID0gVFJVRSkKCiNmaWx0ZXIgbG9jYWxpdGllcyBmb3IgdGhlIGZvY2FsIGdlbnVzCm1pY3JhX2xvYyA8LSBsb2MgJT4lIAogIGZpbHRlcihnZW51cyA9PSAibWljcmFyY2h1cyIpCiAgCiN1c2Ugc291cmNlZCBwbG90X2xvY3NfbGVhZmxldCBzY3JpcHQgdG8gcGxvdCBsb2NhbGl0aWVzCm1pY3JhX21hcCA8LSBwbG90X2xvY3NfbGVhZmxldChtaWNyYV9sb2MsICJyZXByb2R1Y3RpdmVfbW9kZSIpCgptaWNyYV9tYXAKCiMgc2F2ZSB0aGUgbWFwCm1hcHZpZXc6Om1hcHNob3QobWljcmFfbWFwLCB1cmwgPSBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgIm1pY3JhX21hcC5odG1sIiksIGZpbGUgPSBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgIm1pY3JhX21hcC5wZGYiKSkKYGBgCgoKYGBge3J9CnN1bW1hcnlfbGlzdF9taWNyYSRzdW1tYXJ5X3BjYQpsb2FkaW5nc19taWNyYSA8LSBzdW1tYXJ5X2xpc3RfbWljcmEkc3VtbWFyeV9wY2Ekcm90YXRpb24Ka25pdHI6OmthYmxlKHJvdW5kKGxvYWRpbmdzX21pY3JhWywxOjNdLDMpKSAjVGFibGUgb2YgbG9hZGluZyBzY29yZXMgZm9yIHRoZSBmaXJzdCAzIFBDcy4gCmBgYAoKIyMjIE5pdmVhcGhhc21hCgpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1UUlVFfQpzdW1tYXJ5X2xpc3Rfbml2ZSA8LSBzcGVjaWVzX3BjYV9mdW4obG9jX2NsaW0sICJuaXZlYXBoYXNtYSIpCm5pdmVfcGxvdCA8LSBwbG90X2NsaW1fcGNhKHN1bW1hcnlfbGlzdF9uaXZlJGxvY19jbGltLCBzdW1tYXJ5X2xpc3Rfbml2ZSRzdW1tYXJ5X3BjYSwgZmFjdG9yID0gInJlcHJvZHVjdGl2ZV9tb2RlIikKCm5pdmVfcGxvdAoKIyBzYXZlIHRoZSBwbG90IApodG1sd2lkZ2V0czo6c2F2ZVdpZGdldChuaXZlX3Bsb3QsIGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCAibml2ZWFwaGFzbWFfcGNhLmh0bWwiKSwgc2VsZmNvbnRhaW5lZCA9IFRSVUUpCgojZmlsdGVyIGxvY2FsaXRpZXMgZm9yIHRoZSBmb2NhbCBnZW51cwpuaXZlX2xvYyA8LSBsb2MgJT4lIAogIGZpbHRlcihnZW51cyA9PSAibml2ZWFwaGFzbWEiKQogIAojdXNlIHNvdXJjZWQgcGxvdF9sb2NzX2xlYWZsZXQgc2NyaXB0IHRvIHBsb3QgbG9jYWxpdGllcwpuaXZlX21hcCA8LSBwbG90X2xvY3NfbGVhZmxldChuaXZlX2xvYywgInJlcHJvZHVjdGl2ZV9tb2RlIikKCm5pdmVfbWFwCgojIHNhdmUgdGhlIG1hcAptYXB2aWV3OjptYXBzaG90KG5pdmVfbWFwLCB1cmwgPSBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgIm5pdmVfbWFwLmh0bWwiKSwgZmlsZSA9IGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCAibml2ZV9tYXAucGRmIikpCgpgYGAKCmBgYHtyfQpzdW1tYXJ5X2xpc3Rfbml2ZSRzdW1tYXJ5X3BjYQpsb2FkaW5nc19uaXZlIDwtIHN1bW1hcnlfbGlzdF9uaXZlJHN1bW1hcnlfcGNhJHJvdGF0aW9uCmtuaXRyOjprYWJsZShyb3VuZChsb2FkaW5nc19uaXZlWywxOjNdLDMpKSAjVGFibGUgb2YgbG9hZGluZyBzY29yZXMgZm9yIHRoZSBmaXJzdCAzIFBDcy4gCmBgYAoKCk5vdyBJJ20gZ29pbmcgdG8gcGVyZm9ybSBlbnZpcm9ubWVudGFsIG5pY2hlIGZhY3RvciBhbmFseXNpcyB3aXRoIHNleHVhbCBhbmQgYXNleHVhbCBwb3B1bGF0aW9ucyB3aXRoaW4gdGhlIHNwZWNpZXMuCmBgYHtyIGNhY2hlPVRSVUUsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMgZ2V0IGJhY2tncm91bmQgZW52J3QgZm9yIHRoZSBzcGVjaWVzCm5pdmVfYmdfZW52IDwtIGJnX2Vudl9jcm9wKAogIG5pdmVfbG9jLAogIHNwZWNpZXMgPSAiYW5udWxhdGEiLAogIGVudmlyb25tZW50ID0gdywKICBidWZmZXIgPSAwLjUKKQoKI2VuZmEgZm9yIHRoZSBzZXh1YWwgc3BlY2llcwpuaXZlX3NleHVhbF9lbmZhIDwtIGVuZmFfY2FsY19mdW4oCiAgbG9jcyA9IG5pdmVfbG9jLAogIHNwZWNpZXMgPSAiYW5udWxhdGEiLAogIHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIsCiAgbWFza19yYXN0ZXIgPSBuaXZlX2JnX2VudgopCgojZW5mYSBmb3IgdGhlIGFzZXh1YWwgc3BlY2llcwpuaXZlX2FzZXh1YWxfZW5mYSA8LSBlbmZhX2NhbGNfZnVuKAogIGxvY3MgPSBuaXZlX2xvYywKICBzcGVjaWVzID0gImFubnVsYXRhIiwKICByZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIiwKICBtYXNrX3Jhc3RlciA9IG5pdmVfYmdfZW52CikKCiMgd3JpdGUgc2NvcmVzIHRvIGNzdnMKcmVhZHI6OndyaXRlX2NzdigKICBuaXZlX2FzZXh1YWxfZW5mYSRtICU+JSBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJtYXJnaW5hbGl0eSIpLAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgIm5pdmVfYXNleHVhbF9tYXJnaW5hbGl0eV9zY29yZS5jc3YiKQopCgpyZWFkcjo6d3JpdGVfY3N2KAogIG5pdmVfc2V4dWFsX2VuZmEkbSAlPiUgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAibWFyZ2luYWxpdHkiKSwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJuaXZlX3NleHVhbF9tYXJnaW5hbGl0eV9zY29yZS5jc3YiKQopCgojcGxvdCB0aGUgbWFyZ2luYWxpdHkgc2NvcmVzCm5pdmVfbWFyZ2luYWxpdHkgPC0KICBtYXJnaW5hbGl0eV9sb2xsaXBvcCgKICAgIHNleF9tYXJnID0gbml2ZV9zZXh1YWxfZW5mYSRtLAogICAgYXNleF9tYXJnID0gbml2ZV9hc2V4dWFsX2VuZmEkbSwKICAgIGZ1bGxfc3BlY2llc19uYW1lID0gIk5pdmVhcGhhc21hIGFubnVsYXRhIgogICkKCm5pdmVfbWFyZ2luYWxpdHkKCmdnc2F2ZSgKICAibml2ZV9tYXJnaW5hbGl0eV9sb2xsaXBvcC5wbmciLAogIHBsb3QgPSBuaXZlX21hcmdpbmFsaXR5LAogIGRldmljZSA9ICJwbmciLAogIHBhdGggPSBwbG90X3BhdGgsCiAgZHBpID0gInJldGluYSIKKQpgYGAKCgoKQSBjb3VwbGUgZGlmZmVyZW50IHdheXMgdG8gdmlzdWFsaXplIHRoZSBlbnZpcm9ubWVudGFsIHZhcmlhdGlvbi4gMSkgU2NhdHRlcnBsb3QgdmlzdWFsaXphdGlvbnMgb2YgbWFyZ2luYWxpdHkgdnMgYXhpcyAxIG9mIHRoZSBzcGVjaWFsaXphdGlvbiB3aXRoIHRoZSBsYWJlbHMgcmVtb3ZlZCAodGhleSBtYWtlIHRoaW5ncyBpbmRpc2Nlcm5hYmxlKS4gUmVkID0gb2NjdXBpZWQgZS1zcGFjZS4gR3JheSA9IEJhY2tncm91bmQgZS1zcGFjZS4gMikgRU5GQSBoaXN0b2dyYW0gdmlzdWFsaXphdGlvbnMgb2YgbWFyZ2luYWxpdHkgYW5kIHNwZWNpYWxpemF0aW9uIGF4ZXMuIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlIHdpdGggY29sb3JzIGNvcnJlc3BvbmRpbmcgdG8gc2V4dWFsIHZzLiBhc2V4dWFsIHBvcHVsYXRpb25zLiAKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMjIyAxKSBFTkZBIHNjYXR0ZXJwbG90CiNhY2Nlc3MgdGhlIHJlbGV2YW50IHZhbHVlcyBmb3IgcGxvdHRpbmcKbml2ZV9hc2V4dWFsX2RmIDwtIG5pdmVfYXNleHVhbF9lbmZhJGxpICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgYmluZF9jb2xzKHByID0gbml2ZV9hc2V4dWFsX2VuZmEkcHIpCgpyZWFkcjo6d3JpdGVfY3N2KG5pdmVfYXNleHVhbF9kZiwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAibml2ZV9hc2V4dWFsX21hcmdpbmFsaXR5X2RmLmNzdiIpKQoKbml2ZV9zZXh1YWxfZGYgPC0gbml2ZV9zZXh1YWxfZW5mYSRsaSAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGJpbmRfY29scyhwciA9IG5pdmVfc2V4dWFsX2VuZmEkcHIpCgpyZWFkcjo6d3JpdGVfY3N2KG5pdmVfc2V4dWFsX2RmLCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJuaXZlX3NleHVhbF9tYXJnaW5hbGl0eV9kZi5jc3YiKSkKCiMgYXNleHVhbApuaXZlX2VuZmFfc3BlY19hc2V4dWFsIDwtIGVuZmFfaGV4X3Bsb3Qobml2ZV9hc2V4dWFsX2RmLCBtYXJnID0gTWFyLCBzcGVjID0gU3BlMSwgcmVwcm9fbW9kZSA9ICJBc2V4dWFsIikKCmdnc2F2ZSgibml2ZV9lbmZhX3NwZWNfYXNleHVhbC5wbmciLAogICAgICAgcGxvdCA9IG5pdmVfZW5mYV9zcGVjX2FzZXh1YWwsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiNzZXh1YWwKbml2ZV9lbmZhX3NwZWNfc2V4dWFsIDwtIGVuZmFfaGV4X3Bsb3Qobml2ZV9zZXh1YWxfZGYsIG1hcmcgPSBNYXIsIHNwZWMgPSBTcGUxLCByZXByb19tb2RlID0gIlNleHVhbCIpCgpnZ3NhdmUoIm5pdmVfZW5mYV9zcGVjX3NleHVhbC5wbmciLAogICAgICAgcGxvdCA9IG5pdmVfZW5mYV9zcGVjX3NleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKIyMjIDIpIEVORkEgaGlzdG9ncmFtCiNhc2V4dWFsCmhpc3Qobml2ZV9hc2V4dWFsX2VuZmEpCnRpdGxlKG1haW4gPSAiQXNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJuaXZlX2FzZXh1YWxfZW5mYV9oaXN0LnBuZyIpKQpoaXN0KG5pdmVfYXNleHVhbF9lbmZhKQp0aXRsZShtYWluID0gIkFzZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKI3NleHVhbApoaXN0KG5pdmVfc2V4dWFsX2VuZmEpCnRpdGxlKG1haW4gPSAiU2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQoKcG5nKGZpbGVuYW1lID0gZmlsZS5wYXRoKHBsb3RfcGF0aCwgIm5pdmVfc2V4dWFsX2VuZmFfaGlzdC5wbmciKSkKaGlzdChuaXZlX3NleHVhbF9lbmZhKQp0aXRsZShtYWluID0gIlNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKZGV2Lm9mZigpCgojIyMgMykgUENBIG9mIHRvdGFsIGUtc3BhY2UKbml2ZV90b3RhbF9wY2EgPC0gdG90YWxfY2xpbWF0ZV9wY2FfcGxvdChiZ19lbnYgPSBuaXZlX2JnX2VudiwgbG9jcyA9IG5pdmVfbG9jLCBnZW51cyA9ICJOaXZlYXBoYXNtYSIsIHNwZWNpZXMgPSAiYW5udWxhdGEiKQoKbml2ZV90b3RhbF9wY2EKCmdnc2F2ZSgibml2ZV90b3RhbF9wY2EucG5nIiwKICAgICAgIHBsb3QgPSBuaXZlX3RvdGFsX3BjYSwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKYGBgCgoKVHJ5aW5nIG91dCBhIHJlcGVhdCBvZiB0aGUgYW5hbHlzZXMgd2l0aCByZWR1Y2VkIGVudmlyb25tZW50YWwgc3BhY2UuClByaW9yaXRpemluZyB2YXJpYWJsZXMgdGhhdCB3aWxsIGxpbWl0IHRoZWlyIGRpc3RyaWJ1dGlvbiAoaS5lLiB2YXJpYWJsZXMgdGhhdCByZXByZXNlbnQgdGhlIGV4dHJlbWVzKS4gQWZ0ZXIgY29ycmVsYXRpb24gYW5hbHlzaXMsIHdlJ3JlIGxlZnQgd2l0aCBCSU80LCBCSU84LCBCSU85LCBCSU8xMSwgQklPMTUsIEJJTzE3CmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgUENBIG9mIGJhY2tncm91bmQgZS1zcGFjZS4gUmVzdWx0aW5nIGxpc3QgaXMgYSBjb3JyZWxhdGlvbiBoZWF0bWFwIChjb3JfaGVhdG1hcCksIGEgdGliYmxlIG9mIHRoZSByYXN0ZXJzIHdpdGggY29ycmVsYXRpb24gPiB0aGUgY3V0b2ZmIChkZWZhdWx0IGlzIDAuNzUpLCBhbmQgYSB0aWJibGUgb2YgYWxsIHBhaXJ3aXNlIGNvcnJlbGF0aW9ucwpuaXZlX3BjYSA8LSByYXN0ZXJfY29ycmVsYXRpb24ocmFzdGVyX3N0YWNrID0gbml2ZV9iZ19lbnYpCm5pdmVfcGNhJGNvcl9oZWF0bWFwCm5pdmVfcGNhJHRvcF9jb3IgJT4lIGtuaXRyOjprYWJsZSgpCgpnZ3NhdmUoIm5pdmVfcGNhX2NvcnIucG5nIiwKICAgICAgIHBsb3QgPSBuaXZlX3BjYSRjb3JfaGVhdG1hcCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKIyB3cml0ZSBjb3JyZWxhdGlvbiBkYXRhIGZyYW1lIHRvIGZpbGUKcmVhZHI6OndyaXRlX2NzdihuaXZlX3BjYSR0b3BfY29yLCBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJuaXZlX3RvcF9jb3IuY3N2IikpCgpgYGAKClJlcGVhdCB0aGUgYW5hbHlzaXMgd2l0aCB0aGUgcmVkdWNlZCBkYXRhIHNldC4KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Kd19uaXZlIDwtIHJhc3Rlcjo6c3Vic2V0KHcsIGMoImJpbzQiLCAiYmlvOCIsICJiaW85IiwgImJpbzExIiwgImJpbzE1IiwgImJpbzE3IikpCgojZ2V0IGJhY2tncm91bmQgZW52J3QgZm9yIHRoZSBzcGVjaWVzCm5pdmVfYmdfZW52X3N1YnNldCA8LSBiZ19lbnZfY3JvcChuaXZlX2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXMgPSAiYW5udWxhdGEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBlbnZpcm9ubWVudCA9IHdfbml2ZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciA9IDAuNSkKCiNlbmZhIGZvciB0aGUgc2V4dWFsIHNwZWNpZXMKbml2ZV9zZXh1YWxfZW5mYV9zdWJzZXQgPC0gZW5mYV9jYWxjX2Z1bihsb2NzID0gbml2ZV9sb2MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJhbm51bGF0YSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXNrX3Jhc3RlciA9IG5pdmVfYmdfZW52X3N1YnNldCkKCiNlbmZhIGZvciB0aGUgYXNleHVhbCBzcGVjaWVzCm5pdmVfYXNleHVhbF9lbmZhX3N1YnNldCA8LSBlbmZhX2NhbGNfZnVuKGxvY3MgPSBuaXZlX2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJhbm51bGF0YSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXNrX3Jhc3RlciA9IG5pdmVfYmdfZW52X3N1YnNldCkKCiMgd3JpdGUgbWFyZ2luYWxpdHkgc2NvcmVzIHRvIGNzdgpyZWFkcjo6d3JpdGVfY3N2KAogIG5pdmVfYXNleHVhbF9lbmZhX3N1YnNldCRtICU+JSBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJtYXJnaW5hbGl0eSIpLAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgIm5pdmVfc3Vic2V0X2FzZXh1YWxfbWFyZ2luYWxpdHlfc2NvcmUuY3N2IikKKQoKcmVhZHI6OndyaXRlX2NzdigKICBuaXZlX3NleHVhbF9lbmZhX3N1YnNldCRtICU+JSBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJtYXJnaW5hbGl0eSIpLAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgIm5pdmVfc3Vic2V0X3NleHVhbF9tYXJnaW5hbGl0eV9zY29yZS5jc3YiKQopCgojIHBsb3QgdGhlIG1hcmdpbmFsaXR5IHNjb3JlcwpuaXZlX3N1YnNldF9tYXJnaW5hbGl0eSA8LQogIG1hcmdpbmFsaXR5X2xvbGxpcG9wKAogICAgc2V4X21hcmcgPSBuaXZlX3NleHVhbF9lbmZhX3N1YnNldCRtLAogICAgYXNleF9tYXJnID0gbml2ZV9hc2V4dWFsX2VuZmFfc3Vic2V0JG0sCiAgICBmdWxsX3NwZWNpZXNfbmFtZSA9ICJOaXZlYXBoYXNtYSBhbm51bGF0YSIKICApCgpuaXZlX3N1YnNldF9tYXJnaW5hbGl0eQoKZ2dzYXZlKCJuaXZlX3N1YnNldF9tYXJnaW5hbGl0eS5wbmciLAogICAgICAgcGxvdCA9IG5pdmVfc3Vic2V0X21hcmdpbmFsaXR5LAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgpgYGAKClZpc3VhbGl6ZSB3aXRoIHRoZSByZWR1Y2VkIGRhdGEgc2V0LgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojIyMgMSkgRU5GQSBzY2F0dGVycGxvdAojIGFjY2VzcyB0aGUgcmVsZXZhbnQgdmFsdWVzIGZvciBwbG90dGluZwpuaXZlX2FzZXh1YWxfZGZfc3Vic2V0IDwtIG5pdmVfYXNleHVhbF9lbmZhX3N1YnNldCRsaSAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGJpbmRfY29scyhwciA9IG5pdmVfYXNleHVhbF9lbmZhX3N1YnNldCRwcikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgbml2ZV9hc2V4dWFsX2RmX3N1YnNldCwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJuaXZlX2FzZXh1YWxfZGZfc3Vic2V0LmNzdiIpCikKCgpuaXZlX3NleHVhbF9kZl9zdWJzZXQgPC0gbml2ZV9zZXh1YWxfZW5mYV9zdWJzZXQkbGkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBiaW5kX2NvbHMocHIgPSBuaXZlX3NleHVhbF9lbmZhX3N1YnNldCRwcikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgbml2ZV9zZXh1YWxfZGZfc3Vic2V0LAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgIm5pdmVfc2V4dWFsX2RmX3N1YnNldC5jc3YiKQopCgojIGFzZXh1YWwKbml2ZV9zdWJzZXRfZW5mYV9zcGVjX2FzZXh1YWwgPC0gZW5mYV9oZXhfcGxvdChuaXZlX2FzZXh1YWxfZGZfc3Vic2V0LCBtYXJnID0gTWFyLCBzcGVjID0gU3BlMSwgcmVwcm9fbW9kZSA9ICJBc2V4dWFsIikKCmdnc2F2ZSgibml2ZV9zdWJzZXRfZW5mYV9zcGVjX2FzZXh1YWwucG5nIiwKICAgICAgIHBsb3QgPSBuaXZlX3N1YnNldF9lbmZhX3NwZWNfYXNleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKIyBzZXh1YWwKbml2ZV9zdWJzZXRfZW5mYV9zcGVjX3NleHVhbCA8LSBlbmZhX2hleF9wbG90KG5pdmVfc2V4dWFsX2RmX3N1YnNldCwgbWFyZyA9IE1hciwgc3BlYyA9IFNwZTEsIHJlcHJvX21vZGUgPSAiU2V4dWFsIikKCmdnc2F2ZSgibml2ZV9zdWJzZXRfZW5mYV9zcGVjX3NleHVhbC5wbmciLAogICAgICAgcGxvdCA9IG5pdmVfc3Vic2V0X2VuZmFfc3BlY19zZXh1YWwsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMjIyAyKSBFTkZBIGhpc3RvZ3JhbQojIGFzZXh1YWwKaGlzdChuaXZlX2FzZXh1YWxfZW5mYV9zdWJzZXQpCnRpdGxlKG1haW4gPSAiQXNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJuaXZlX3N1YnNldF9hc2V4dWFsX2VuZmFfaGlzdC5wbmciKSkKaGlzdChuaXZlX2FzZXh1YWxfZW5mYV9zdWJzZXQpCnRpdGxlKG1haW4gPSAiQXNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKZGV2Lm9mZigpCgoKIyBzZXh1YWwKaGlzdChuaXZlX3NleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJTZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCgpwbmcoZmlsZW5hbWUgPSBmaWxlLnBhdGgocGxvdF9wYXRoLCAibml2ZV9zdWJzZXRfc2V4dWFsX2VuZmFfaGlzdC5wbmciKSkKaGlzdChuaXZlX3NleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJTZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKIyMjIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlCm5pdmVfc3Vic2V0X3RvdGFsX3BjYSA8LSB0b3RhbF9jbGltYXRlX3BjYV9wbG90KGJnX2VudiA9IG5pdmVfYmdfZW52X3N1YnNldCwgbG9jcyA9IG5pdmVfbG9jLCBnZW51cyA9ICJOaXZlYXBoYXNtYSIsIHNwZWNpZXMgPSAiYW5udWxhdGEiKQoKbml2ZV9zdWJzZXRfdG90YWxfcGNhCgpnZ3NhdmUoIm5pdmVfc3Vic2V0X3RvdGFsX3BjYS5wbmciLAogICAgICAgcGxvdCA9IG5pdmVfc3Vic2V0X3RvdGFsX3BjYSwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKIyBzYXZlIGVuZmEgb2JqZWN0cyBhbmQgcmVtb3ZlIHRoZW0gZnJvbSB0aGUgZW52aXJvbm1lbnQuIFRoZXkgdGFrZSB1cCBhIGxvdCBvZiBtZW1vcnkuCnNhdmVSRFMobml2ZV9zZXh1YWxfZW5mYSwgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgIm5pdmVfc2V4dWFsX2VuZmEuUkRTIikpCnJtKG5pdmVfc2V4dWFsX2VuZmEpCgpzYXZlUkRTKG5pdmVfYXNleHVhbF9lbmZhLCBmaWxlID0gZmlsZS5wYXRoKG9ial9wYXRoLCAibml2ZV9hc2V4dWFsX2VuZmEuUkRTIikpCnJtKG5pdmVfYXNleHVhbF9lbmZhKQoKc2F2ZVJEUyhuaXZlX3NleHVhbF9lbmZhX3N1YnNldCwKICAgICAgICBmaWxlID0gZmlsZS5wYXRoKG9ial9wYXRoLCAibml2ZV9zdWJzZXRfc2V4dWFsX2VuZmEuUkRTIikpCnJtKG5pdmVfc2V4dWFsX2VuZmFfc3Vic2V0KQoKc2F2ZVJEUyhuaXZlX2FzZXh1YWxfZW5mYV9zdWJzZXQsCiAgICAgICAgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgIm5pdmVfc3Vic2V0X2FzZXh1YWxfZW5mYS5SRFMiKSkKcm0obml2ZV9hc2V4dWFsX2VuZmFfc3Vic2V0KQpgYGAKCldlJ3JlIGFsc28gaW50ZXJlc3RlZCBpbiBzZWVpbmcgaWYgYXNleHVhbCBwb3B1bGF0aW9ucyBsaXZlIGluIG1vcmUgdW5zdGFibGUgY2xpbWF0aWMgYXJlYXMgcmVsYXRpdmUgdG8gc2V4dWFsIHBvcHVsYXRpb25zLiAKYGBge3Igd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0Kbml2ZV9sb2NzX2FzZXh1YWwgPC0gbml2ZV9sb2MgJT4lIAogIG11dGF0ZShsYXRfbG9uZyA9IHN0cl9jKGxhdGl0dWRlLCBsb25naXR1ZGUsIHNlcCA9ICJfIikpICU+JSAKICBmaWx0ZXIocmVwcm9kdWN0aXZlX21vZGUgPT0gImFzZXh1YWwiLAogICAgICAgICAhZHVwbGljYXRlZChsYXRfbG9uZykpICU+JSAKICBkcGx5cjo6c2VsZWN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUpCgpuaXZlX2xvY3Nfc2V4dWFsIDwtIG5pdmVfbG9jICU+JSAKICBtdXRhdGUobGF0X2xvbmcgPSBzdHJfYyhsYXRpdHVkZSwgbG9uZ2l0dWRlLCBzZXAgPSAiXyIpKSAlPiUgCiAgZmlsdGVyKHJlcHJvZHVjdGl2ZV9tb2RlID09ICJzZXh1YWwiLAogICAgICAgICAhZHVwbGljYXRlZChsYXRfbG9uZykpICU+JSAKICBkcGx5cjo6c2VsZWN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUpCgpwcmVjaXBfYXNleHVhbF9uaXZlIDwtIHJhc3Rlcjo6ZXh0cmFjdChwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCwgbml2ZV9sb2NzX2FzZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIpCgpwcmVjaXBfc2V4dWFsX25pdmUgPC0gcmFzdGVyOjpleHRyYWN0KHByZWNpcF9zdGFiaWxpdHlfc2NhbGVkLCBuaXZlX2xvY3Nfc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAicHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgpwcmVjaXBfZGZfbml2ZSA8LSBiaW5kX3Jvd3MocHJlY2lwX2FzZXh1YWxfbml2ZSwgcHJlY2lwX3NleHVhbF9uaXZlKQoKcmVhZHI6OndyaXRlX2NzdihwcmVjaXBfZGZfbml2ZSwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAibml2ZV9wcmVjaXBfc3RhYmlsaXR5X2RmLmNzdiIpKQoKbml2ZV9wcmVjaXBfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBwcmVjaXBfZGZfbml2ZSwgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IHByZWNpcF9zdGFiaWxpdHlfc2NhbGVkLCBjb2xvciA9IHJlcHJvZHVjdGl2ZV9tb2RlKSkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuNSwgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gInRyYW5zcGFyZW50IikgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBhbHBoYSA9IDAuNikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAibWFnbWEiKSArCiAgdGhlbWVfZGFyaygpCgpuaXZlX3ByZWNpcF9zdGFiaWxpdHlfcGxvdAoKZ2dzYXZlKCJuaXZlX3ByZWNpcF9zdGFiaWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSBuaXZlX3ByZWNpcF9zdGFiaWxpdHlfcGxvdCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKdGVtcF9hc2V4dWFsX25pdmUgPC0gcmFzdGVyOjpleHRyYWN0KHRlbXBfc3RhYmlsaXR5X3NjYWxlZCwgbml2ZV9sb2NzX2FzZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJ0ZW1wX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiKQoKdGVtcF9zZXh1YWxfbml2ZSA8LSByYXN0ZXI6OmV4dHJhY3QodGVtcF9zdGFiaWxpdHlfc2NhbGVkLCBuaXZlX2xvY3Nfc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAidGVtcF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiKQoKdGVtcF9kZl9uaXZlIDwtIGJpbmRfcm93cyh0ZW1wX2FzZXh1YWxfbml2ZSwgdGVtcF9zZXh1YWxfbml2ZSkKCnJlYWRyOjp3cml0ZV9jc3YodGVtcF9kZl9uaXZlLCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJuaXZlX3RlbXBfc3RhYmlsaXR5X2RmLmNzdiIpKQoKbml2ZV90ZW1wX3N0YWJpbGl0eV9wbG90IDwtIGdncGxvdChkYXRhID0gdGVtcF9kZl9uaXZlLCBhZXMoeCA9IHJlcHJvZHVjdGl2ZV9tb2RlLCB5ID0gdGVtcF9zdGFiaWxpdHlfc2NhbGVkLCBjb2xvciA9IHJlcHJvZHVjdGl2ZV9tb2RlKSkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuNSwgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gInRyYW5zcGFyZW50IikgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBhbHBoYSA9IDAuNikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAibWFnbWEiKSArCiAgdGhlbWVfZGFyaygpCgpuaXZlX3RlbXBfc3RhYmlsaXR5X3Bsb3QKCmdnc2F2ZSgibml2ZV9wcmVjaXBfc3RhYmlsaXR5LnBuZyIsCiAgICAgICBwbG90ID0gbml2ZV90ZW1wX3N0YWJpbGl0eV9wbG90LAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgpvdmVyYWxsX2FzZXh1YWxfbml2ZSA8LSByYXN0ZXI6OmV4dHJhY3Qob3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkLCBuaXZlX2xvY3NfYXNleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIpCgpvdmVyYWxsX3NleHVhbF9uaXZlIDwtIHJhc3Rlcjo6ZXh0cmFjdChvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQsIG5pdmVfbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgpvdmVyYWxsX2RmX25pdmUgPC0gYmluZF9yb3dzKG92ZXJhbGxfYXNleHVhbF9uaXZlLCBvdmVyYWxsX3NleHVhbF9uaXZlKQoKcmVhZHI6OndyaXRlX2NzdihvdmVyYWxsX2RmX25pdmUsIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgIm5pdmVfb3ZlcmFsbF9zdGFiaWxpdHlfZGYuY3N2IikpCgpuaXZlX292ZXJhbGxfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBvdmVyYWxsX2RmX25pdmUsIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSBvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQsIGNvbG9yID0gcmVwcm9kdWN0aXZlX21vZGUpKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC41LCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFscGhhID0gMC42KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCm5pdmVfb3ZlcmFsbF9zdGFiaWxpdHlfcGxvdAoKZ2dzYXZlKCJuaXZlX292ZXJhbGxfc3RhYmlsaXR5LnBuZyIsCiAgICAgICBwbG90ID0gbml2ZV9vdmVyYWxsX3N0YWJpbGl0eV9wbG90LAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCmBgYAoKUHV0IGFsbCBvdXRwdXQgaW50byBzcGVjaWVzLXNwZWNpZmljIHN1YmZvbGRlcnMuCmBgYHtyIHJlc3VsdHM9ImhpZGUifQpuaXZlX291dF9pbnRfcGF0aCA8LSBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgIm5pdmVhcGhhc21hX2FubnVsYXRhIikKbml2ZV9vdXRfcGxvdF9wYXRoIDwtIGZpbGUucGF0aChwbG90X3BhdGgsICJuaXZlYXBoYXNtYV9hbm51bGF0YSIpCm5pdmVfb3V0X3NwcmVhZF9wYXRoIDwtIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgIm5pdmVhcGhhc21hX2FubnVsYXRhIikKbml2ZV9vdXRfb2JqX3BhdGggPC0gZmlsZS5wYXRoKG9ial9wYXRoLCAibml2ZWFwaGFzbWFfYW5udWxhdGEiKQoKIyBtb3ZlIGludGVyYWN0aXZlCm1vdmVfdG9fc3BlY2llcyhpbl9wYXRoID0gaW50ZXJhY3RpdmVfcGF0aCwKICAgICAgICAgICAgICAgIG91dF9wYXRoID0gbml2ZV9vdXRfaW50X3BhdGgsCiAgICAgICAgICAgICAgICBwYXR0ZXJuID0gIm5pdmUiKQojIG1vdmUgcGxvdHMKbW92ZV90b19zcGVjaWVzKGluX3BhdGggPSBwbG90X3BhdGgsCiAgICAgICAgICAgICAgICBvdXRfcGF0aCA9IG5pdmVfb3V0X3Bsb3RfcGF0aCwKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAibml2ZSIpCgojIG1vdmUgc3ByZWFkc2hlZXRzCm1vdmVfdG9fc3BlY2llcyhpbl9wYXRoID0gc3ByZWFkX3BhdGgsCiAgICAgICAgICAgICAgICBvdXRfcGF0aCA9IG5pdmVfb3V0X3NwcmVhZF9wYXRoLAogICAgICAgICAgICAgICAgcGF0dGVybiA9ICJuaXZlIikKCiMgbW92ZSBvYmplY3RzCm1vdmVfdG9fc3BlY2llcyhpbl9wYXRoID0gb2JqX3BhdGgsCiAgICAgICAgICAgICAgICBvdXRfcGF0aCA9IG5pdmVfb3V0X29ial9wYXRoLAogICAgICAgICAgICAgICAgcGF0dGVybiA9ICJuaXZlIikKYGBgCgoKIyMjIFNwaW5vdGVjdGFyY2h1cwoKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9VFJVRX0Kc3VtbWFyeV9saXN0X3NwaW4gPC0gc3BlY2llc19wY2FfZnVuKGxvY19jbGltLCAic3Bpbm90ZWN0YXJjaHVzIikKc3Bpbl9wbG90IDwtIHBsb3RfY2xpbV9wY2Eoc3VtbWFyeV9saXN0X3NwaW4kbG9jX2NsaW0sIHN1bW1hcnlfbGlzdF9zcGluJHN1bW1hcnlfcGNhLCBmYWN0b3IgPSAicmVwcm9kdWN0aXZlX21vZGUiKQoKc3Bpbl9wbG90CgojIHNhdmUgdGhlIHBsb3QgCmh0bWx3aWRnZXRzOjpzYXZlV2lkZ2V0KHNwaW5fcGxvdCwgZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJzcGlub3RlY3RhcmNodXNfcGNhLmh0bWwiKSwgc2VsZmNvbnRhaW5lZCA9IFRSVUUpCgojZmlsdGVyIGxvY2FsaXRpZXMgZm9yIHRoZSBmb2NhbCBnZW51cwpzcGluX2xvYyA8LSBsb2MgJT4lIAogIGZpbHRlcihnZW51cyA9PSAic3Bpbm90ZWN0YXJjaHVzIikKICAKI3VzZSBzb3VyY2VkIHBsb3RfbG9jc19sZWFmbGV0IHNjcmlwdCB0byBwbG90IGxvY2FsaXRpZXMKc3Bpbl9tYXAgPC0gcGxvdF9sb2NzX2xlYWZsZXQoc3Bpbl9sb2MsICJyZXByb2R1Y3RpdmVfbW9kZSIpCgpzcGluX21hcAoKIyBzYXZlIHRoZSBtYXAKbWFwdmlldzo6bWFwc2hvdChzcGluX21hcCwgdXJsID0gZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJzcGluX21hcC5odG1sIiksIGZpbGUgPSBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgInNwaW5fbWFwLnBkZiIpKQoKYGBgCgpgYGB7cn0Kc3VtbWFyeV9saXN0X3NwaW4kc3VtbWFyeV9wY2EKbG9hZGluZ3Nfc3BpbiA8LSBzdW1tYXJ5X2xpc3Rfc3BpbiRzdW1tYXJ5X3BjYSRyb3RhdGlvbgprbml0cjo6a2FibGUocm91bmQobG9hZGluZ3Nfc3BpblssMTozXSwzKSkgI1RhYmxlIG9mIGxvYWRpbmcgc2NvcmVzIGZvciB0aGUgZmlyc3QgMyBQQ3MuIApgYGAKCgojIyMgVGVjdGFyY2h1cwpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1UUlVFfQpzdW1tYXJ5X2xpc3RfdGVjdCA8LSBzcGVjaWVzX3BjYV9mdW4obG9jX2NsaW0sICJ0ZWN0YXJjaHVzIikKdGVjdF9wbG90IDwtIHBsb3RfY2xpbV9wY2Eoc3VtbWFyeV9saXN0X3RlY3QkbG9jX2NsaW0sIHN1bW1hcnlfbGlzdF90ZWN0JHN1bW1hcnlfcGNhLCBmYWN0b3IgPSAicmVwcm9kdWN0aXZlX21vZGUiKQoKdGVjdF9wbG90CgojIHNhdmUgdGhlIHBsb3QgCmh0bWx3aWRnZXRzOjpzYXZlV2lkZ2V0KHRlY3RfcGxvdCwgZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJ0ZWN0YXJjaHVzX3BjYS5odG1sIiksIHNlbGZjb250YWluZWQgPSBUUlVFKQoKI2ZpbHRlciBsb2NhbGl0aWVzIGZvciB0aGUgZm9jYWwgZ2VudXMKdGVjdF9sb2MgPC0gbG9jICU+JSAKICBmaWx0ZXIoZ2VudXMgPT0gInRlY3RhcmNodXMiKQogIAojdXNlIHNvdXJjZWQgcGxvdF9sb2NzX2xlYWZsZXQgc2NyaXB0IHRvIHBsb3QgbG9jYWxpdGllcwp0ZWN0X21hcCA8LSBwbG90X2xvY3NfbGVhZmxldCh0ZWN0X2xvYywgInJlcHJvZHVjdGl2ZV9tb2RlIikKCnRlY3RfbWFwCgojIHNhdmUgdGhlIG1hcAptYXB2aWV3OjptYXBzaG90KHRlY3RfbWFwLCB1cmwgPSBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgInRlY3RfbWFwLmh0bWwiKSwgZmlsZSA9IGZpbGUucGF0aChpbnRlcmFjdGl2ZV9wYXRoLCAidGVjdF9tYXAucGRmIikpCgpgYGAKCmBgYHtyfQpzdW1tYXJ5X2xpc3RfdGVjdCRzdW1tYXJ5X3BjYQpsb2FkaW5nc190ZWN0IDwtIHN1bW1hcnlfbGlzdF90ZWN0JHN1bW1hcnlfcGNhJHJvdGF0aW9uCmtuaXRyOjprYWJsZShyb3VuZChsb2FkaW5nc190ZWN0WywxOjNdLDMpKSAjVGFibGUgb2YgbG9hZGluZyBzY29yZXMgZm9yIHRoZSBmaXJzdCAzIFBDcy4gCmBgYAoKIyMjIyBUZWN0YXJjaHVzIG92b2Jlc3N1cwpOb3cgSSdtIGdvaW5nIHRvIHBlcmZvcm0gZW52aXJvbm1lbnRhbCBuaWNoZSBmYWN0b3IgYW5hbHlzaXMgd2l0aCBzZXh1YWwgYW5kIGFzZXh1YWwgcG9wdWxhdGlvbnMgd2l0aGluIHRoZSBzcGVjaWVzLgpgYGB7ciBjYWNoZT1UUlVFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojIGdldCBiYWNrZ3JvdW5kIGVudid0IGZvciB0aGUgc3BlY2llcwp0ZWN0X292b19iZ19lbnYgPC0gYmdfZW52X2Nyb3AoCiAgdGVjdF9sb2MsCiAgc3BlY2llcyA9ICJvdm9iZXNzdXMiLAogIGVudmlyb25tZW50ID0gdywKICBidWZmZXIgPSAwLjUKKQoKI2VuZmEgZm9yIHRoZSBzZXh1YWwgc3BlY2llcwp0ZWN0X292b19zZXh1YWxfZW5mYSA8LSBlbmZhX2NhbGNfZnVuKAogIGxvY3MgPSB0ZWN0X2xvYywKICBzcGVjaWVzID0gIm92b2Jlc3N1cyIsCiAgcmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIiwKICBtYXNrX3Jhc3RlciA9IHRlY3Rfb3ZvX2JnX2VudgopCgojZW5mYSBmb3IgdGhlIGFzZXh1YWwgc3BlY2llcwp0ZWN0X292b19hc2V4dWFsX2VuZmEgPC0gZW5mYV9jYWxjX2Z1bigKICBsb2NzID0gdGVjdF9sb2MsCiAgc3BlY2llcyA9ICJvdm9iZXNzdXMiLAogIHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiLAogIG1hc2tfcmFzdGVyID0gdGVjdF9vdm9fYmdfZW52CikKCiMgd3JpdGUgc2NvcmVzIHRvIGNzdnMKcmVhZHI6OndyaXRlX2NzdigKICB0ZWN0X292b19hc2V4dWFsX2VuZmEkbSAlPiUgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAibWFyZ2luYWxpdHkiKSwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJ0ZWN0X292b19hc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgdGVjdF9vdm9fc2V4dWFsX2VuZmEkbSAlPiUgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAibWFyZ2luYWxpdHkiKSwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJ0ZWN0X292b19zZXh1YWxfbWFyZ2luYWxpdHlfc2NvcmUuY3N2IikKKQoKI3Bsb3QgdGhlIG1hcmdpbmFsaXR5IHNjb3Jlcwp0ZWN0X292b19tYXJnaW5hbGl0eSA8LQogIG1hcmdpbmFsaXR5X2xvbGxpcG9wKAogICAgc2V4X21hcmcgPSB0ZWN0X292b19zZXh1YWxfZW5mYSRtLAogICAgYXNleF9tYXJnID0gdGVjdF9vdm9fYXNleHVhbF9lbmZhJG0sCiAgICBmdWxsX3NwZWNpZXNfbmFtZSA9ICJUZWN0YXJjaHVzIG92b2Jlc3N1cyIKICApCgp0ZWN0X292b19tYXJnaW5hbGl0eQoKZ2dzYXZlKAogICJ0ZWN0X292b19tYXJnaW5hbGl0eV9sb2xsaXBvcC5wbmciLAogIHBsb3QgPSB0ZWN0X292b19tYXJnaW5hbGl0eSwKICBkZXZpY2UgPSAicG5nIiwKICBwYXRoID0gcGxvdF9wYXRoLAogIGRwaSA9ICJyZXRpbmEiCikKYGBgCgoKQSBjb3VwbGUgZGlmZmVyZW50IHdheXMgdG8gdmlzdWFsaXplIHRoZSBlbnZpcm9ubWVudGFsIHZhcmlhdGlvbi4gMSkgU2NhdHRlcnBsb3QgdmlzdWFsaXphdGlvbnMgb2YgbWFyZ2luYWxpdHkgdnMgYXhpcyAxIG9mIHRoZSBzcGVjaWFsaXphdGlvbiB3aXRoIHRoZSBsYWJlbHMgcmVtb3ZlZCAodGhleSBtYWtlIHRoaW5ncyBpbmRpc2Nlcm5hYmxlKS4gUmVkID0gb2NjdXBpZWQgZS1zcGFjZS4gR3JheSA9IEJhY2tncm91bmQgZS1zcGFjZS4gMikgRU5GQSBoaXN0b2dyYW0gdmlzdWFsaXphdGlvbnMgb2YgbWFyZ2luYWxpdHkgYW5kIHNwZWNpYWxpemF0aW9uIGF4ZXMuIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlIHdpdGggY29sb3JzIGNvcnJlc3BvbmRpbmcgdG8gc2V4dWFsIHZzLiBhc2V4dWFsIHBvcHVsYXRpb25zLiAKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMjIyAxKSBFTkZBIHNjYXR0ZXJwbG90CiNhY2Nlc3MgdGhlIHJlbGV2YW50IHZhbHVlcyBmb3IgcGxvdHRpbmcKdGVjdF9vdm9fYXNleHVhbF9kZiA8LSB0ZWN0X292b19hc2V4dWFsX2VuZmEkbGkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBiaW5kX2NvbHMocHIgPSB0ZWN0X292b19hc2V4dWFsX2VuZmEkcHIpCgpyZWFkcjo6d3JpdGVfY3N2KHRlY3Rfb3ZvX2FzZXh1YWxfZGYsIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgInRlY3Rfb3ZvX2FzZXh1YWxfbWFyZ2luYWxpdHlfZGYuY3N2IikpCgp0ZWN0X292b19zZXh1YWxfZGYgPC0gdGVjdF9vdm9fc2V4dWFsX2VuZmEkbGkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBiaW5kX2NvbHMocHIgPSB0ZWN0X292b19zZXh1YWxfZW5mYSRwcikKCnJlYWRyOjp3cml0ZV9jc3YodGVjdF9vdm9fc2V4dWFsX2RmLCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJ0ZWN0X292b19zZXh1YWxfbWFyZ2luYWxpdHlfZGYuY3N2IikpCgojIGFzZXh1YWwKdGVjdF9vdm9fZW5mYV9zcGVjX2FzZXh1YWwgPC0gZW5mYV9oZXhfcGxvdCh0ZWN0X292b19hc2V4dWFsX2RmLCBtYXJnID0gTWFyLCBzcGVjID0gU3BlMSwgcmVwcm9fbW9kZSA9ICJBc2V4dWFsIikKCmdnc2F2ZSgidGVjdF9vdm9fZW5mYV9zcGVjX2FzZXh1YWwucG5nIiwKICAgICAgIHBsb3QgPSB0ZWN0X292b19lbmZhX3NwZWNfYXNleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKI3NleHVhbAp0ZWN0X292b19lbmZhX3NwZWNfc2V4dWFsIDwtIGVuZmFfaGV4X3Bsb3QodGVjdF9vdm9fc2V4dWFsX2RmLCBtYXJnID0gTWFyLCBzcGVjID0gU3BlMSwgcmVwcm9fbW9kZSA9ICJTZXh1YWwiKQoKZ2dzYXZlKCJ0ZWN0X292b19lbmZhX3NwZWNfc2V4dWFsLnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9vdm9fZW5mYV9zcGVjX3NleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKIyMjIDIpIEVORkEgaGlzdG9ncmFtCiNhc2V4dWFsCmhpc3QodGVjdF9vdm9fYXNleHVhbF9lbmZhKQp0aXRsZShtYWluID0gIkFzZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCgpwbmcoZmlsZW5hbWUgPSBmaWxlLnBhdGgocGxvdF9wYXRoLCAidGVjdF9vdm9fYXNleHVhbF9lbmZhX2hpc3QucG5nIikpCmhpc3QodGVjdF9vdm9fYXNleHVhbF9lbmZhKQp0aXRsZShtYWluID0gIkFzZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKI3NleHVhbApoaXN0KHRlY3Rfb3ZvX3NleHVhbF9lbmZhKQp0aXRsZShtYWluID0gIlNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJ0ZWN0X292b19zZXh1YWxfZW5mYV9oaXN0LnBuZyIpKQpoaXN0KHRlY3Rfb3ZvX3NleHVhbF9lbmZhKQp0aXRsZShtYWluID0gIlNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKZGV2Lm9mZigpCgojIyMgMykgUENBIG9mIHRvdGFsIGUtc3BhY2UKdGVjdF9vdm9fdG90YWxfcGNhIDwtIHRvdGFsX2NsaW1hdGVfcGNhX3Bsb3QoYmdfZW52ID0gdGVjdF9vdm9fYmdfZW52LCBsb2NzID0gdGVjdF9sb2MsIGdlbnVzID0gIlRlY3RhcmNodXMiLCBzcGVjaWVzID0gIm92b2Jlc3N1cyIpCgp0ZWN0X292b190b3RhbF9wY2EKCmdnc2F2ZSgidGVjdF9vdm9fdG90YWxfcGNhLnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9vdm9fdG90YWxfcGNhLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgpgYGAKClRyeWluZyBvdXQgYSByZXBlYXQgb2YgdGhlIGFuYWx5c2VzIHdpdGggcmVkdWNlZCBlbnZpcm9ubWVudGFsIHNwYWNlLgpQcmlvcml0aXppbmcgdmFyaWFibGVzIHRoYXQgd2lsbCBsaW1pdCB0aGVpciBkaXN0cmlidXRpb24gKGkuZS4gdmFyaWFibGVzIHRoYXQgcmVwcmVzZW50IHRoZSBleHRyZW1lcykuIEFmdGVyIGNvcnJlbGF0aW9uIGFuYWx5c2lzLCB3ZSdyZSBsZWZ0IHdpdGggQklPNCwgQklPOCwgQklPMTEsIEJJTzE1LCBCSU8xNwpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIFBDQSBvZiBiYWNrZ3JvdW5kIGUtc3BhY2UuIFJlc3VsdGluZyBsaXN0IGlzIGEgY29ycmVsYXRpb24gaGVhdG1hcCAoY29yX2hlYXRtYXApLCBhIHRpYmJsZSBvZiB0aGUgcmFzdGVycyB3aXRoIGNvcnJlbGF0aW9uID4gdGhlIGN1dG9mZiAoZGVmYXVsdCBpcyAwLjc1KSwgYW5kIGEgdGliYmxlIG9mIGFsbCBwYWlyd2lzZSBjb3JyZWxhdGlvbnMKdGVjdF9vdm9fcGNhIDwtIHJhc3Rlcl9jb3JyZWxhdGlvbihyYXN0ZXJfc3RhY2sgPSB0ZWN0X292b19iZ19lbnYpCnRlY3Rfb3ZvX3BjYSRjb3JfaGVhdG1hcAp0ZWN0X292b19wY2EkdG9wX2NvciAlPiUga25pdHI6OmthYmxlKCkKCmdnc2F2ZSgidGVjdF9vdm9fcGNhX2NvcnIucG5nIiwKICAgICAgIHBsb3QgPSB0ZWN0X292b19wY2EkY29yX2hlYXRtYXAsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMgd3JpdGUgY29ycmVsYXRpb24gZGF0YSBmcmFtZSB0byBmaWxlCnJlYWRyOjp3cml0ZV9jc3YodGVjdF9vdm9fcGNhJHRvcF9jb3IsIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgInRlY3Rfb3ZvX3RvcF9jb3IuY3N2IikpCgpgYGAKClJlcGVhdCB0aGUgYW5hbHlzaXMgd2l0aCB0aGUgcmVkdWNlZCBkYXRhIHNldC4KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Kd190ZWN0X292byA8LSByYXN0ZXI6OnN1YnNldCh3LCBjKCJiaW80IiwgImJpbzgiLCAiYmlvMTEiLCAiYmlvMTUiLCAiYmlvMTciKSkKCiNnZXQgYmFja2dyb3VuZCBlbnYndCBmb3IgdGhlIHNwZWNpZXMKdGVjdF9vdm9fYmdfZW52X3N1YnNldCA8LSBiZ19lbnZfY3JvcCh0ZWN0X2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXMgPSAib3ZvYmVzc3VzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52aXJvbm1lbnQgPSB3X3RlY3Rfb3ZvLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyID0gMC41KQoKI2VuZmEgZm9yIHRoZSBzZXh1YWwgc3BlY2llcwp0ZWN0X292b19zZXh1YWxfZW5mYV9zdWJzZXQgPC0gZW5mYV9jYWxjX2Z1bihsb2NzID0gdGVjdF9sb2MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJvdm9iZXNzdXMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFza19yYXN0ZXIgPSB0ZWN0X292b19iZ19lbnZfc3Vic2V0KQoKI2VuZmEgZm9yIHRoZSBhc2V4dWFsIHNwZWNpZXMKdGVjdF9vdm9fYXNleHVhbF9lbmZhX3N1YnNldCA8LSBlbmZhX2NhbGNfZnVuKGxvY3MgPSB0ZWN0X2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJvdm9iZXNzdXMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFza19yYXN0ZXIgPSB0ZWN0X292b19iZ19lbnZfc3Vic2V0KQoKIyB3cml0ZSBtYXJnaW5hbGl0eSBzY29yZXMgdG8gY3N2CnJlYWRyOjp3cml0ZV9jc3YoCiAgdGVjdF9vdm9fYXNleHVhbF9lbmZhX3N1YnNldCRtICU+JSBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJtYXJnaW5hbGl0eSIpLAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgInRlY3Rfb3ZvX3N1YnNldF9hc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgdGVjdF9vdm9fc2V4dWFsX2VuZmFfc3Vic2V0JG0gJT4lIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm1hcmdpbmFsaXR5IiksCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9vdm9fc3Vic2V0X3NleHVhbF9tYXJnaW5hbGl0eV9zY29yZS5jc3YiKQopCgojIHBsb3QgdGhlIG1hcmdpbmFsaXR5IHNjb3Jlcwp0ZWN0X292b19zdWJzZXRfbWFyZ2luYWxpdHkgPC0KICBtYXJnaW5hbGl0eV9sb2xsaXBvcCgKICAgIHNleF9tYXJnID0gdGVjdF9vdm9fc2V4dWFsX2VuZmFfc3Vic2V0JG0sCiAgICBhc2V4X21hcmcgPSB0ZWN0X292b19hc2V4dWFsX2VuZmFfc3Vic2V0JG0sCiAgICBmdWxsX3NwZWNpZXNfbmFtZSA9ICJUZWN0YXJjaHVzIG92b2Jlc3N1cyIKICApCgp0ZWN0X292b19zdWJzZXRfbWFyZ2luYWxpdHkKCmdnc2F2ZSgidGVjdF9vdm9fc3Vic2V0X21hcmdpbmFsaXR5LnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9vdm9fc3Vic2V0X21hcmdpbmFsaXR5LAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgpgYGAKClZpc3VhbGl6ZSB3aXRoIHRoZSByZWR1Y2VkIGRhdGEgc2V0LgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojIyMgMSkgRU5GQSBzY2F0dGVycGxvdAojIGFjY2VzcyB0aGUgcmVsZXZhbnQgdmFsdWVzIGZvciBwbG90dGluZwp0ZWN0X292b19hc2V4dWFsX2RmX3N1YnNldCA8LSB0ZWN0X292b19hc2V4dWFsX2VuZmFfc3Vic2V0JGxpICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgYmluZF9jb2xzKHByID0gdGVjdF9vdm9fYXNleHVhbF9lbmZhX3N1YnNldCRwcikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgdGVjdF9vdm9fYXNleHVhbF9kZl9zdWJzZXQsCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9vdm9fYXNleHVhbF9kZl9zdWJzZXQuY3N2IikKKQoKCnRlY3Rfb3ZvX3NleHVhbF9kZl9zdWJzZXQgPC0gdGVjdF9vdm9fc2V4dWFsX2VuZmFfc3Vic2V0JGxpICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgYmluZF9jb2xzKHByID0gdGVjdF9vdm9fc2V4dWFsX2VuZmFfc3Vic2V0JHByKQoKcmVhZHI6OndyaXRlX2NzdigKICB0ZWN0X292b19zZXh1YWxfZGZfc3Vic2V0LAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgInRlY3Rfb3ZvX3NleHVhbF9kZl9zdWJzZXQuY3N2IikKKQoKIyBhc2V4dWFsCnRlY3Rfb3ZvX3N1YnNldF9lbmZhX3NwZWNfYXNleHVhbCA8LSBlbmZhX2hleF9wbG90KHRlY3Rfb3ZvX2FzZXh1YWxfZGZfc3Vic2V0LCBtYXJnID0gTWFyLCBzcGVjID0gU3BlMSwgcmVwcm9fbW9kZSA9ICJBc2V4dWFsIikKCmdnc2F2ZSgidGVjdF9vdm9fc3Vic2V0X2VuZmFfc3BlY19hc2V4dWFsLnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9vdm9fc3Vic2V0X2VuZmFfc3BlY19hc2V4dWFsLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgojIHNleHVhbAp0ZWN0X292b19zdWJzZXRfZW5mYV9zcGVjX3NleHVhbCA8LSBlbmZhX2hleF9wbG90KHRlY3Rfb3ZvX3NleHVhbF9kZl9zdWJzZXQsIG1hcmcgPSBNYXIsIHNwZWMgPSBTcGUxLCByZXByb19tb2RlID0gIlNleHVhbCIpCgpnZ3NhdmUoInRlY3Rfb3ZvX3N1YnNldF9lbmZhX3NwZWNfc2V4dWFsLnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9vdm9fc3Vic2V0X2VuZmFfc3BlY19zZXh1YWwsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMjIyAyKSBFTkZBIGhpc3RvZ3JhbQojIGFzZXh1YWwKaGlzdCh0ZWN0X292b19hc2V4dWFsX2VuZmFfc3Vic2V0KQp0aXRsZShtYWluID0gIkFzZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCgpwbmcoZmlsZW5hbWUgPSBmaWxlLnBhdGgocGxvdF9wYXRoLCAidGVjdF9vdm9fc3Vic2V0X2FzZXh1YWxfZW5mYV9oaXN0LnBuZyIpKQpoaXN0KHRlY3Rfb3ZvX2FzZXh1YWxfZW5mYV9zdWJzZXQpCnRpdGxlKG1haW4gPSAiQXNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKZGV2Lm9mZigpCgoKIyBzZXh1YWwKaGlzdCh0ZWN0X292b19zZXh1YWxfZW5mYV9zdWJzZXQpCnRpdGxlKG1haW4gPSAiU2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQoKcG5nKGZpbGVuYW1lID0gZmlsZS5wYXRoKHBsb3RfcGF0aCwgInRlY3Rfb3ZvX3N1YnNldF9zZXh1YWxfZW5mYV9oaXN0LnBuZyIpKQpoaXN0KHRlY3Rfb3ZvX3NleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJTZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKIyMjIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlCnRlY3Rfb3ZvX3N1YnNldF90b3RhbF9wY2EgPC0gdG90YWxfY2xpbWF0ZV9wY2FfcGxvdChiZ19lbnYgPSB0ZWN0X292b19iZ19lbnZfc3Vic2V0LCBsb2NzID0gdGVjdF9sb2MsIGdlbnVzID0gIlRlY3RhcmNodXMiLCBzcGVjaWVzID0gIm92b2Jlc3N1cyIpCgp0ZWN0X292b19zdWJzZXRfdG90YWxfcGNhCgpnZ3NhdmUoInRlY3Rfb3ZvX3N1YnNldF90b3RhbF9wY2EucG5nIiwKICAgICAgIHBsb3QgPSB0ZWN0X292b19zdWJzZXRfdG90YWxfcGNhLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgojIHNhdmUgZW5mYSBvYmplY3RzIGFuZCByZW1vdmUgdGhlbSBmcm9tIHRoZSBlbnZpcm9ubWVudC4gVGhleSB0YWtlIHVwIGEgbG90IG9mIG1lbW9yeS4Kc2F2ZVJEUyh0ZWN0X292b19zZXh1YWxfZW5mYSwgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgInRlY3Rfb3ZvX3NleHVhbF9lbmZhLlJEUyIpKQpybSh0ZWN0X292b19zZXh1YWxfZW5mYSkKCnNhdmVSRFModGVjdF9vdm9fYXNleHVhbF9lbmZhLCBmaWxlID0gZmlsZS5wYXRoKG9ial9wYXRoLCAidGVjdF9vdm9fYXNleHVhbF9lbmZhLlJEUyIpKQpybSh0ZWN0X292b19hc2V4dWFsX2VuZmEpCgpzYXZlUkRTKHRlY3Rfb3ZvX3NleHVhbF9lbmZhX3N1YnNldCwKICAgICAgICBmaWxlID0gZmlsZS5wYXRoKG9ial9wYXRoLCAidGVjdF9vdm9fc3Vic2V0X3NleHVhbF9lbmZhLlJEUyIpKQpybSh0ZWN0X292b19zZXh1YWxfZW5mYV9zdWJzZXQpCgpzYXZlUkRTKHRlY3Rfb3ZvX2FzZXh1YWxfZW5mYV9zdWJzZXQsCiAgICAgICAgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgInRlY3Rfb3ZvX3N1YnNldF9hc2V4dWFsX2VuZmEuUkRTIikpCnJtKHRlY3Rfb3ZvX2FzZXh1YWxfZW5mYV9zdWJzZXQpCmBgYAoKV2UncmUgYWxzbyBpbnRlcmVzdGVkIGluIHNlZWluZyBpZiBhc2V4dWFsIHBvcHVsYXRpb25zIGxpdmUgaW4gbW9yZSB1bnN0YWJsZSBjbGltYXRpYyBhcmVhcyByZWxhdGl2ZSB0byBzZXh1YWwgcG9wdWxhdGlvbnMuIApgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQp0ZWN0X292b19sb2NzX2FzZXh1YWwgPC0gdGVjdF9sb2MgJT4lIAogIG11dGF0ZShsYXRfbG9uZyA9IHN0cl9jKGxhdGl0dWRlLCBsb25naXR1ZGUsIHNlcCA9ICJfIikpICU+JSAKICBmaWx0ZXIocmVwcm9kdWN0aXZlX21vZGUgPT0gImFzZXh1YWwiLAogICAgICAgICBzcGVjaWVzID09ICJvdm9iZXNzdXMiLAogICAgICAgICAhZHVwbGljYXRlZChsYXRfbG9uZykpICU+JSAKICBkcGx5cjo6c2VsZWN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUpCgp0ZWN0X292b19sb2NzX3NleHVhbCA8LSB0ZWN0X2xvYyAlPiUgCiAgbXV0YXRlKGxhdF9sb25nID0gc3RyX2MobGF0aXR1ZGUsIGxvbmdpdHVkZSwgc2VwID0gIl8iKSkgJT4lIAogIGZpbHRlcihyZXByb2R1Y3RpdmVfbW9kZSA9PSAic2V4dWFsIiwKICAgICAgICAgc3BlY2llcyA9PSAib3ZvYmVzc3VzIiwKICAgICAgICAgIWR1cGxpY2F0ZWQobGF0X2xvbmcpKSAlPiUgCiAgZHBseXI6OnNlbGVjdChsb25naXR1ZGUsIGxhdGl0dWRlKQoKcHJlY2lwX2FzZXh1YWxfdGVjdF9vdm8gPC0gcmFzdGVyOjpleHRyYWN0KHByZWNpcF9zdGFiaWxpdHlfc2NhbGVkLCB0ZWN0X292b19sb2NzX2FzZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIpCgpwcmVjaXBfc2V4dWFsX3RlY3Rfb3ZvIDwtIHJhc3Rlcjo6ZXh0cmFjdChwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCwgdGVjdF9vdm9fbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIikKCnByZWNpcF9kZl90ZWN0X292byA8LSBiaW5kX3Jvd3MocHJlY2lwX2FzZXh1YWxfdGVjdF9vdm8sIHByZWNpcF9zZXh1YWxfdGVjdF9vdm8pCgpyZWFkcjo6d3JpdGVfY3N2KHByZWNpcF9kZl90ZWN0X292bywgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9vdm9fcHJlY2lwX3N0YWJpbGl0eV9kZi5jc3YiKSkKCnRlY3Rfb3ZvX3ByZWNpcF9zdGFiaWxpdHlfcGxvdCA8LSBnZ3Bsb3QoZGF0YSA9IHByZWNpcF9kZl90ZWN0X292bywgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IHByZWNpcF9zdGFiaWxpdHlfc2NhbGVkLCBjb2xvciA9IHJlcHJvZHVjdGl2ZV9tb2RlKSkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuNSwgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gInRyYW5zcGFyZW50IikgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBhbHBoYSA9IDAuNikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAibWFnbWEiKSArCiAgdGhlbWVfZGFyaygpCgp0ZWN0X292b19wcmVjaXBfc3RhYmlsaXR5X3Bsb3QKCmdnc2F2ZSgidGVjdF9vdm9fcHJlY2lwX3N0YWJpbGl0eS5wbmciLAogICAgICAgcGxvdCA9IHRlY3Rfb3ZvX3ByZWNpcF9zdGFiaWxpdHlfcGxvdCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKdGVtcF9hc2V4dWFsX3RlY3Rfb3ZvIDwtIHJhc3Rlcjo6ZXh0cmFjdCh0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIHRlY3Rfb3ZvX2xvY3NfYXNleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInRlbXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIpCgp0ZW1wX3NleHVhbF90ZWN0X292byA8LSByYXN0ZXI6OmV4dHJhY3QodGVtcF9zdGFiaWxpdHlfc2NhbGVkLCB0ZWN0X292b19sb2NzX3NleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInRlbXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAic2V4dWFsIikKCnRlbXBfZGZfdGVjdF9vdm8gPC0gYmluZF9yb3dzKHRlbXBfYXNleHVhbF90ZWN0X292bywgdGVtcF9zZXh1YWxfdGVjdF9vdm8pCgpyZWFkcjo6d3JpdGVfY3N2KHRlbXBfZGZfdGVjdF9vdm8sIAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgInRlY3Rfb3ZvX3RlbXBfc3RhYmlsaXR5X2RmLmNzdiIpKQoKdGVjdF9vdm9fdGVtcF9zdGFiaWxpdHlfcGxvdCA8LSBnZ3Bsb3QoZGF0YSA9IHRlbXBfZGZfdGVjdF9vdm8sIGFlcyh4ID0gcmVwcm9kdWN0aXZlX21vZGUsIHkgPSB0ZW1wX3N0YWJpbGl0eV9zY2FsZWQsIGNvbG9yID0gcmVwcm9kdWN0aXZlX21vZGUpKSArCiAgZ2VvbV9ib3hwbG90KHdpZHRoID0gMC41LCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFscGhhID0gMC42KSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJtYWdtYSIpICsKICB0aGVtZV9kYXJrKCkKCnRlY3Rfb3ZvX3RlbXBfc3RhYmlsaXR5X3Bsb3QKCmdnc2F2ZSgidGVjdF9vdm9fcHJlY2lwX3N0YWJpbGl0eS5wbmciLAogICAgICAgcGxvdCA9IHRlY3Rfb3ZvX3RlbXBfc3RhYmlsaXR5X3Bsb3QsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCm92ZXJhbGxfYXNleHVhbF90ZWN0X292byA8LSByYXN0ZXI6OmV4dHJhY3Qob3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkLCB0ZWN0X292b19sb2NzX2FzZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gImFzZXh1YWwiKQoKb3ZlcmFsbF9zZXh1YWxfdGVjdF9vdm8gPC0gcmFzdGVyOjpleHRyYWN0KG92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCwgdGVjdF9vdm9fbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgpvdmVyYWxsX2RmX3RlY3Rfb3ZvIDwtIGJpbmRfcm93cyhvdmVyYWxsX2FzZXh1YWxfdGVjdF9vdm8sIG92ZXJhbGxfc2V4dWFsX3RlY3Rfb3ZvKQoKcmVhZHI6OndyaXRlX2NzdihvdmVyYWxsX2RmX3RlY3Rfb3ZvLCAKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJ0ZWN0X292b19vdmVyYWxsX3N0YWJpbGl0eV9kZi5jc3YiKSkKCnRlY3Rfb3ZvX292ZXJhbGxfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBvdmVyYWxsX2RmX3RlY3Rfb3ZvLCBhZXMoeCA9IHJlcHJvZHVjdGl2ZV9tb2RlLCB5ID0gb3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkLCBjb2xvciA9IHJlcHJvZHVjdGl2ZV9tb2RlKSkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuNSwgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gInRyYW5zcGFyZW50IikgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBhbHBoYSA9IDAuNikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAibWFnbWEiKSArCiAgdGhlbWVfZGFyaygpCgp0ZWN0X292b19vdmVyYWxsX3N0YWJpbGl0eV9wbG90CgpnZ3NhdmUoInRlY3Rfb3ZvX292ZXJhbGxfc3RhYmlsaXR5LnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9vdm9fb3ZlcmFsbF9zdGFiaWxpdHlfcGxvdCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQpgYGAKCgpQdXQgYWxsIG91dHB1dCBpbnRvIHNwZWNpZXMtc3BlY2lmaWMgc3ViZm9sZGVycy4KYGBge3IgcmVzdWx0cz0iaGlkZSJ9CnRlY3Rfb3ZvX291dF9pbnRfcGF0aCA8LSBmaWxlLnBhdGgoaW50ZXJhY3RpdmVfcGF0aCwgInRlY3RhcmNodXNfb3ZvYmVzc3VzIikKdGVjdF9vdm9fb3V0X3Bsb3RfcGF0aCA8LSBmaWxlLnBhdGgocGxvdF9wYXRoLCAidGVjdGFyY2h1c19vdm9iZXNzdXMiKQp0ZWN0X292b19vdXRfc3ByZWFkX3BhdGggPC0gZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdGFyY2h1c19vdm9iZXNzdXMiKQp0ZWN0X292b19vdXRfb2JqX3BhdGggPC0gZmlsZS5wYXRoKG9ial9wYXRoLCAidGVjdGFyY2h1c19vdm9iZXNzdXMiKQoKIyBtb3ZlIGludGVyYWN0aXZlCm1vdmVfdG9fc3BlY2llcyhpbl9wYXRoID0gaW50ZXJhY3RpdmVfcGF0aCwKICAgICAgICAgICAgICAgIG91dF9wYXRoID0gdGVjdF9vdm9fb3V0X2ludF9wYXRoLAogICAgICAgICAgICAgICAgcGF0dGVybiA9ICJ0ZWN0X292byIpCiMgbW92ZSBwbG90cwptb3ZlX3RvX3NwZWNpZXMoaW5fcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgICAgICAgICAgIG91dF9wYXRoID0gdGVjdF9vdm9fb3V0X3Bsb3RfcGF0aCwKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAidGVjdF9vdm8iKQoKIyBtb3ZlIHNwcmVhZHNoZWV0cwptb3ZlX3RvX3NwZWNpZXMoaW5fcGF0aCA9IHNwcmVhZF9wYXRoLAogICAgICAgICAgICAgICAgb3V0X3BhdGggPSB0ZWN0X292b19vdXRfc3ByZWFkX3BhdGgsCiAgICAgICAgICAgICAgICBwYXR0ZXJuID0gInRlY3Rfb3ZvIikKCiMgbW92ZSBvYmplY3RzCm1vdmVfdG9fc3BlY2llcyhpbl9wYXRoID0gb2JqX3BhdGgsCiAgICAgICAgICAgICAgICBvdXRfcGF0aCA9IHRlY3Rfb3ZvX291dF9vYmpfcGF0aCwKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAidGVjdF9vdm8iKQpgYGAKCgojIyMjIFRlY3RhcmNodXMgaHV0dG9uaQoKTm93IEknbSBnb2luZyB0byBwZXJmb3JtIGVudmlyb25tZW50YWwgbmljaGUgZmFjdG9yIGFuYWx5c2lzIHdpdGggc2V4dWFsIGFuZCBhc2V4dWFsIHBvcHVsYXRpb25zIHdpdGhpbiB0aGUgc3BlY2llcy4KYGBge3IgY2FjaGU9VFJVRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyBnZXQgYmFja2dyb3VuZCBlbnYndCBmb3IgdGhlIHNwZWNpZXMKdGVjdF9odXR0X2JnX2VudiA8LSBiZ19lbnZfY3JvcCgKICB0ZWN0X2xvYywKICBzcGVjaWVzID0gImh1dHRvbmkiLAogIGVudmlyb25tZW50ID0gdywKICBidWZmZXIgPSAwLjUKKQoKI2VuZmEgZm9yIHRoZSBzZXh1YWwgc3BlY2llcwp0ZWN0X2h1dHRfc2V4dWFsX2VuZmEgPC0gZW5mYV9jYWxjX2Z1bigKICBsb2NzID0gdGVjdF9sb2MsCiAgc3BlY2llcyA9ICJodXR0b25pIiwKICByZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiLAogIG1hc2tfcmFzdGVyID0gdGVjdF9odXR0X2JnX2VudgopCgojZW5mYSBmb3IgdGhlIGFzZXh1YWwgc3BlY2llcwp0ZWN0X2h1dHRfYXNleHVhbF9lbmZhIDwtIGVuZmFfY2FsY19mdW4oCiAgbG9jcyA9IHRlY3RfbG9jLAogIHNwZWNpZXMgPSAiaHV0dG9uaSIsCiAgcmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIsCiAgbWFza19yYXN0ZXIgPSB0ZWN0X2h1dHRfYmdfZW52CikKCiMgd3JpdGUgc2NvcmVzIHRvIGNzdnMKcmVhZHI6OndyaXRlX2NzdigKICB0ZWN0X2h1dHRfYXNleHVhbF9lbmZhJG0gJT4lIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm1hcmdpbmFsaXR5IiksCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9odXR0X2FzZXh1YWxfbWFyZ2luYWxpdHlfc2NvcmUuY3N2IikKKQoKcmVhZHI6OndyaXRlX2NzdigKICB0ZWN0X2h1dHRfc2V4dWFsX2VuZmEkbSAlPiUgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAibWFyZ2luYWxpdHkiKSwKICBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJ0ZWN0X2h1dHRfc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCiNwbG90IHRoZSBtYXJnaW5hbGl0eSBzY29yZXMKdGVjdF9odXR0X21hcmdpbmFsaXR5IDwtCiAgbWFyZ2luYWxpdHlfbG9sbGlwb3AoCiAgICBzZXhfbWFyZyA9IHRlY3RfaHV0dF9zZXh1YWxfZW5mYSRtLAogICAgYXNleF9tYXJnID0gdGVjdF9odXR0X2FzZXh1YWxfZW5mYSRtLAogICAgZnVsbF9zcGVjaWVzX25hbWUgPSAiVGVjdGFyY2h1cyBodXR0b25pIgogICkKCnRlY3RfaHV0dF9tYXJnaW5hbGl0eQoKZ2dzYXZlKAogICJ0ZWN0X2h1dHRfbWFyZ2luYWxpdHlfbG9sbGlwb3AucG5nIiwKICBwbG90ID0gdGVjdF9odXR0X21hcmdpbmFsaXR5LAogIGRldmljZSA9ICJwbmciLAogIHBhdGggPSBwbG90X3BhdGgsCiAgZHBpID0gInJldGluYSIKKQpgYGAKCkEgY291cGxlIGRpZmZlcmVudCB3YXlzIHRvIHZpc3VhbGl6ZSB0aGUgZW52aXJvbm1lbnRhbCB2YXJpYXRpb24uIDEpIFNjYXR0ZXJwbG90IHZpc3VhbGl6YXRpb25zIG9mIG1hcmdpbmFsaXR5IHZzIGF4aXMgMSBvZiB0aGUgc3BlY2lhbGl6YXRpb24gd2l0aCB0aGUgbGFiZWxzIHJlbW92ZWQgKHRoZXkgbWFrZSB0aGluZ3MgaW5kaXNjZXJuYWJsZSkuIFJlZCA9IG9jY3VwaWVkIGUtc3BhY2UuIEdyYXkgPSBCYWNrZ3JvdW5kIGUtc3BhY2UuIDIpIEVORkEgaGlzdG9ncmFtIHZpc3VhbGl6YXRpb25zIG9mIG1hcmdpbmFsaXR5IGFuZCBzcGVjaWFsaXphdGlvbiBheGVzLiAzKSBQQ0Egb2YgdG90YWwgZS1zcGFjZSB3aXRoIGNvbG9ycyBjb3JyZXNwb25kaW5nIHRvIHNleHVhbCB2cy4gYXNleHVhbCBwb3B1bGF0aW9ucy4gCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIyMgMSkgRU5GQSBzY2F0dGVycGxvdAojYWNjZXNzIHRoZSByZWxldmFudCB2YWx1ZXMgZm9yIHBsb3R0aW5nCnRlY3RfaHV0dF9hc2V4dWFsX2RmIDwtIHRlY3RfaHV0dF9hc2V4dWFsX2VuZmEkbGkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBiaW5kX2NvbHMocHIgPSB0ZWN0X2h1dHRfYXNleHVhbF9lbmZhJHByKQoKcmVhZHI6OndyaXRlX2Nzdih0ZWN0X2h1dHRfYXNleHVhbF9kZiwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9odXR0X2FzZXh1YWxfbWFyZ2luYWxpdHlfZGYuY3N2IikpCgp0ZWN0X2h1dHRfc2V4dWFsX2RmIDwtIHRlY3RfaHV0dF9zZXh1YWxfZW5mYSRsaSAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGJpbmRfY29scyhwciA9IHRlY3RfaHV0dF9zZXh1YWxfZW5mYSRwcikKCnJlYWRyOjp3cml0ZV9jc3YodGVjdF9odXR0X3NleHVhbF9kZiwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9odXR0X3NleHVhbF9tYXJnaW5hbGl0eV9kZi5jc3YiKSkKCiMgYXNleHVhbAp0ZWN0X2h1dHRfZW5mYV9zcGVjX2FzZXh1YWwgPC0gZW5mYV9oZXhfcGxvdCh0ZWN0X2h1dHRfYXNleHVhbF9kZiwgbWFyZyA9IE1hciwgc3BlYyA9IFNwZTEsIHJlcHJvX21vZGUgPSAiQXNleHVhbCIpCgpnZ3NhdmUoInRlY3RfaHV0dF9lbmZhX3NwZWNfYXNleHVhbC5wbmciLAogICAgICAgcGxvdCA9IHRlY3RfaHV0dF9lbmZhX3NwZWNfYXNleHVhbCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKI3NleHVhbAp0ZWN0X2h1dHRfZW5mYV9zcGVjX3NleHVhbCA8LSBlbmZhX2hleF9wbG90KHRlY3RfaHV0dF9zZXh1YWxfZGYsIG1hcmcgPSBNYXIsIHNwZWMgPSBTcGUxLCByZXByb19tb2RlID0gIlNleHVhbCIpCgpnZ3NhdmUoInRlY3RfaHV0dF9lbmZhX3NwZWNfc2V4dWFsLnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9odXR0X2VuZmFfc3BlY19zZXh1YWwsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMjIyAyKSBFTkZBIGhpc3RvZ3JhbQojYXNleHVhbApoaXN0KHRlY3RfaHV0dF9hc2V4dWFsX2VuZmEpCnRpdGxlKG1haW4gPSAiQXNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJ0ZWN0X2h1dHRfYXNleHVhbF9lbmZhX2hpc3QucG5nIikpCmhpc3QodGVjdF9odXR0X2FzZXh1YWxfZW5mYSkKdGl0bGUobWFpbiA9ICJBc2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQpkZXYub2ZmKCkKCiNzZXh1YWwKaGlzdCh0ZWN0X2h1dHRfc2V4dWFsX2VuZmEpCnRpdGxlKG1haW4gPSAiU2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQoKcG5nKGZpbGVuYW1lID0gZmlsZS5wYXRoKHBsb3RfcGF0aCwgInRlY3RfaHV0dF9zZXh1YWxfZW5mYV9oaXN0LnBuZyIpKQpoaXN0KHRlY3RfaHV0dF9zZXh1YWxfZW5mYSkKdGl0bGUobWFpbiA9ICJTZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKIyMjIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlCnRlY3RfaHV0dF90b3RhbF9wY2EgPC0gdG90YWxfY2xpbWF0ZV9wY2FfcGxvdChiZ19lbnYgPSB0ZWN0X2h1dHRfYmdfZW52LCBsb2NzID0gdGVjdF9sb2MsIGdlbnVzID0gIlRlY3RhcmNodXMiLCBzcGVjaWVzID0gImh1dHRvbmkiKQoKdGVjdF9odXR0X3RvdGFsX3BjYQoKZ2dzYXZlKCJ0ZWN0X2h1dHRfdG90YWxfcGNhLnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9odXR0X3RvdGFsX3BjYSwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKYGBgCgpUcnlpbmcgb3V0IGEgcmVwZWF0IG9mIHRoZSBhbmFseXNlcyB3aXRoIHJlZHVjZWQgZW52aXJvbm1lbnRhbCBzcGFjZS4KUHJpb3JpdGl6aW5nIHZhcmlhYmxlcyB0aGF0IHdpbGwgbGltaXQgdGhlaXIgZGlzdHJpYnV0aW9uIChpLmUuIHZhcmlhYmxlcyB0aGF0IHJlcHJlc2VudCB0aGUgZXh0cmVtZXMpLiBBZnRlciBjb3JyZWxhdGlvbiBhbmFseXNpcywgd2UncmUgbGVmdCB3aXRoIEJJTzQsIEJJTzgsIEJJTzExLCBCSU8xNSwgQklPMTcKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBQQ0Egb2YgYmFja2dyb3VuZCBlLXNwYWNlLiBSZXN1bHRpbmcgbGlzdCBpcyBhIGNvcnJlbGF0aW9uIGhlYXRtYXAgKGNvcl9oZWF0bWFwKSwgYSB0aWJibGUgb2YgdGhlIHJhc3RlcnMgd2l0aCBjb3JyZWxhdGlvbiA+IHRoZSBjdXRvZmYgKGRlZmF1bHQgaXMgMC43NSksIGFuZCBhIHRpYmJsZSBvZiBhbGwgcGFpcndpc2UgY29ycmVsYXRpb25zCnRlY3RfaHV0dF9wY2EgPC0gcmFzdGVyX2NvcnJlbGF0aW9uKHJhc3Rlcl9zdGFjayA9IHRlY3RfaHV0dF9iZ19lbnYpCnRlY3RfaHV0dF9wY2EkY29yX2hlYXRtYXAKdGVjdF9odXR0X3BjYSR0b3BfY29yICU+JSBrbml0cjo6a2FibGUoKQoKZ2dzYXZlKCJ0ZWN0X2h1dHRfcGNhX2NvcnIucG5nIiwKICAgICAgIHBsb3QgPSB0ZWN0X2h1dHRfcGNhJGNvcl9oZWF0bWFwLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgojIHdyaXRlIGNvcnJlbGF0aW9uIGRhdGEgZnJhbWUgdG8gZmlsZQpyZWFkcjo6d3JpdGVfY3N2KHRlY3RfaHV0dF9wY2EkdG9wX2NvciwgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9odXR0X3RvcF9jb3IuY3N2IikpCgpgYGAKClJlcGVhdCB0aGUgYW5hbHlzaXMgd2l0aCB0aGUgcmVkdWNlZCBkYXRhIHNldC4KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Kd190ZWN0X2h1dHQgPC0gcmFzdGVyOjpzdWJzZXQodywgYygiYmlvNCIsICJiaW84IiwgImJpbzExIiwgImJpbzE1IiwgImJpbzE3IikpCgojZ2V0IGJhY2tncm91bmQgZW52J3QgZm9yIHRoZSBzcGVjaWVzCnRlY3RfaHV0dF9iZ19lbnZfc3Vic2V0IDwtIGJnX2Vudl9jcm9wKHRlY3RfbG9jLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2llcyA9ICJodXR0b25pIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52aXJvbm1lbnQgPSB3X3RlY3RfaHV0dCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciA9IDAuNSkKCiNlbmZhIGZvciB0aGUgc2V4dWFsIHNwZWNpZXMKdGVjdF9odXR0X3NleHVhbF9lbmZhX3N1YnNldCA8LSBlbmZhX2NhbGNfZnVuKGxvY3MgPSB0ZWN0X2xvYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzID0gImh1dHRvbmkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFza19yYXN0ZXIgPSB0ZWN0X2h1dHRfYmdfZW52X3N1YnNldCkKCiNlbmZhIGZvciB0aGUgYXNleHVhbCBzcGVjaWVzCnRlY3RfaHV0dF9hc2V4dWFsX2VuZmFfc3Vic2V0IDwtIGVuZmFfY2FsY19mdW4obG9jcyA9IHRlY3RfbG9jLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzID0gImh1dHRvbmkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFza19yYXN0ZXIgPSB0ZWN0X2h1dHRfYmdfZW52X3N1YnNldCkKCiMgd3JpdGUgbWFyZ2luYWxpdHkgc2NvcmVzIHRvIGNzdgpyZWFkcjo6d3JpdGVfY3N2KAogIHRlY3RfaHV0dF9hc2V4dWFsX2VuZmFfc3Vic2V0JG0gJT4lIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gIm1hcmdpbmFsaXR5IiksCiAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9odXR0X3N1YnNldF9hc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgdGVjdF9odXR0X3NleHVhbF9lbmZhX3N1YnNldCRtICU+JSBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJtYXJnaW5hbGl0eSIpLAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgInRlY3RfaHV0dF9zdWJzZXRfc2V4dWFsX21hcmdpbmFsaXR5X3Njb3JlLmNzdiIpCikKCiMgcGxvdCB0aGUgbWFyZ2luYWxpdHkgc2NvcmVzCnRlY3RfaHV0dF9zdWJzZXRfbWFyZ2luYWxpdHkgPC0KICBtYXJnaW5hbGl0eV9sb2xsaXBvcCgKICAgIHNleF9tYXJnID0gdGVjdF9odXR0X3NleHVhbF9lbmZhX3N1YnNldCRtLAogICAgYXNleF9tYXJnID0gdGVjdF9odXR0X2FzZXh1YWxfZW5mYV9zdWJzZXQkbSwKICAgIGZ1bGxfc3BlY2llc19uYW1lID0gIlRlY3RhcmNodXMgaHV0dG9uaSIKICApCgp0ZWN0X2h1dHRfc3Vic2V0X21hcmdpbmFsaXR5CgpnZ3NhdmUoInRlY3RfaHV0dF9zdWJzZXRfbWFyZ2luYWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSB0ZWN0X2h1dHRfc3Vic2V0X21hcmdpbmFsaXR5LAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgpgYGAKClZpc3VhbGl6ZSB3aXRoIHRoZSByZWR1Y2VkIGRhdGEgc2V0LgpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojIyMgMSkgRU5GQSBzY2F0dGVycGxvdAojIGFjY2VzcyB0aGUgcmVsZXZhbnQgdmFsdWVzIGZvciBwbG90dGluZwp0ZWN0X2h1dHRfYXNleHVhbF9kZl9zdWJzZXQgPC0gdGVjdF9odXR0X2FzZXh1YWxfZW5mYV9zdWJzZXQkbGkgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBiaW5kX2NvbHMocHIgPSB0ZWN0X2h1dHRfYXNleHVhbF9lbmZhX3N1YnNldCRwcikKCnJlYWRyOjp3cml0ZV9jc3YoCiAgdGVjdF9odXR0X2FzZXh1YWxfZGZfc3Vic2V0LAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgInRlY3RfaHV0dF9hc2V4dWFsX2RmX3N1YnNldC5jc3YiKQopCgoKdGVjdF9odXR0X3NleHVhbF9kZl9zdWJzZXQgPC0gdGVjdF9odXR0X3NleHVhbF9lbmZhX3N1YnNldCRsaSAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGJpbmRfY29scyhwciA9IHRlY3RfaHV0dF9zZXh1YWxfZW5mYV9zdWJzZXQkcHIpCgpyZWFkcjo6d3JpdGVfY3N2KAogIHRlY3RfaHV0dF9zZXh1YWxfZGZfc3Vic2V0LAogIGZpbGUucGF0aChzcHJlYWRfcGF0aCwgInRlY3RfaHV0dF9zZXh1YWxfZGZfc3Vic2V0LmNzdiIpCikKCiMgYXNleHVhbAp0ZWN0X2h1dHRfc3Vic2V0X2VuZmFfc3BlY19hc2V4dWFsIDwtIGVuZmFfaGV4X3Bsb3QodGVjdF9odXR0X2FzZXh1YWxfZGZfc3Vic2V0LCBtYXJnID0gTWFyLCBzcGVjID0gU3BlMSwgcmVwcm9fbW9kZSA9ICJBc2V4dWFsIikKCmdnc2F2ZSgidGVjdF9odXR0X3N1YnNldF9lbmZhX3NwZWNfYXNleHVhbC5wbmciLAogICAgICAgcGxvdCA9IHRlY3RfaHV0dF9zdWJzZXRfZW5mYV9zcGVjX2FzZXh1YWwsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMgc2V4dWFsCnRlY3RfaHV0dF9zdWJzZXRfZW5mYV9zcGVjX3NleHVhbCA8LSBlbmZhX2hleF9wbG90KHRlY3RfaHV0dF9zZXh1YWxfZGZfc3Vic2V0LCBtYXJnID0gTWFyLCBzcGVjID0gU3BlMSwgcmVwcm9fbW9kZSA9ICJTZXh1YWwiKQoKZ2dzYXZlKCJ0ZWN0X2h1dHRfc3Vic2V0X2VuZmFfc3BlY19zZXh1YWwucG5nIiwKICAgICAgIHBsb3QgPSB0ZWN0X2h1dHRfc3Vic2V0X2VuZmFfc3BlY19zZXh1YWwsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKCiMjIyAyKSBFTkZBIGhpc3RvZ3JhbQojIGFzZXh1YWwKaGlzdCh0ZWN0X2h1dHRfYXNleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJBc2V4dWFsIiwgYWRqID0gMC43LCBsaW5lID0gLTEyKQoKcG5nKGZpbGVuYW1lID0gZmlsZS5wYXRoKHBsb3RfcGF0aCwgInRlY3RfaHV0dF9zdWJzZXRfYXNleHVhbF9lbmZhX2hpc3QucG5nIikpCmhpc3QodGVjdF9odXR0X2FzZXh1YWxfZW5mYV9zdWJzZXQpCnRpdGxlKG1haW4gPSAiQXNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKZGV2Lm9mZigpCgoKIyBzZXh1YWwKaGlzdCh0ZWN0X2h1dHRfc2V4dWFsX2VuZmFfc3Vic2V0KQp0aXRsZShtYWluID0gIlNleHVhbCIsIGFkaiA9IDAuNywgbGluZSA9IC0xMikKCnBuZyhmaWxlbmFtZSA9IGZpbGUucGF0aChwbG90X3BhdGgsICJ0ZWN0X2h1dHRfc3Vic2V0X3NleHVhbF9lbmZhX2hpc3QucG5nIikpCmhpc3QodGVjdF9odXR0X3NleHVhbF9lbmZhX3N1YnNldCkKdGl0bGUobWFpbiA9ICJTZXh1YWwiLCBhZGogPSAwLjcsIGxpbmUgPSAtMTIpCmRldi5vZmYoKQoKIyMjIDMpIFBDQSBvZiB0b3RhbCBlLXNwYWNlCnRlY3RfaHV0dF9zdWJzZXRfdG90YWxfcGNhIDwtIHRvdGFsX2NsaW1hdGVfcGNhX3Bsb3QoYmdfZW52ID0gdGVjdF9odXR0X2JnX2Vudl9zdWJzZXQsIGxvY3MgPSB0ZWN0X2xvYywgZ2VudXMgPSAiVGVjdGFyY2h1cyIsIHNwZWNpZXMgPSAiaHV0dG9uaSIpCgp0ZWN0X2h1dHRfc3Vic2V0X3RvdGFsX3BjYQoKZ2dzYXZlKCJ0ZWN0X2h1dHRfc3Vic2V0X3RvdGFsX3BjYS5wbmciLAogICAgICAgcGxvdCA9IHRlY3RfaHV0dF9zdWJzZXRfdG90YWxfcGNhLAogICAgICAgZGV2aWNlID0gInBuZyIsCiAgICAgICBwYXRoID0gcGxvdF9wYXRoLAogICAgICAgZHBpID0gInJldGluYSIpCgojIHNhdmUgZW5mYSBvYmplY3RzIGFuZCByZW1vdmUgdGhlbSBmcm9tIHRoZSBlbnZpcm9ubWVudC4gVGhleSB0YWtlIHVwIGEgbG90IG9mIG1lbW9yeS4Kc2F2ZVJEUyh0ZWN0X2h1dHRfc2V4dWFsX2VuZmEsIGZpbGUgPSBmaWxlLnBhdGgob2JqX3BhdGgsICJ0ZWN0X2h1dHRfc2V4dWFsX2VuZmEuUkRTIikpCnJtKHRlY3RfaHV0dF9zZXh1YWxfZW5mYSkKCnNhdmVSRFModGVjdF9odXR0X2FzZXh1YWxfZW5mYSwgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgInRlY3RfaHV0dF9hc2V4dWFsX2VuZmEuUkRTIikpCnJtKHRlY3RfaHV0dF9hc2V4dWFsX2VuZmEpCgpzYXZlUkRTKHRlY3RfaHV0dF9zZXh1YWxfZW5mYV9zdWJzZXQsCiAgICAgICAgZmlsZSA9IGZpbGUucGF0aChvYmpfcGF0aCwgInRlY3RfaHV0dF9zdWJzZXRfc2V4dWFsX2VuZmEuUkRTIikpCnJtKHRlY3RfaHV0dF9zZXh1YWxfZW5mYV9zdWJzZXQpCgpzYXZlUkRTKHRlY3RfaHV0dF9hc2V4dWFsX2VuZmFfc3Vic2V0LAogICAgICAgIGZpbGUgPSBmaWxlLnBhdGgob2JqX3BhdGgsICJ0ZWN0X2h1dHRfc3Vic2V0X2FzZXh1YWxfZW5mYS5SRFMiKSkKcm0odGVjdF9odXR0X2FzZXh1YWxfZW5mYV9zdWJzZXQpCmBgYAoKV2UncmUgYWxzbyBpbnRlcmVzdGVkIGluIHNlZWluZyBpZiBhc2V4dWFsIHBvcHVsYXRpb25zIGxpdmUgaW4gbW9yZSB1bnN0YWJsZSBjbGltYXRpYyBhcmVhcyByZWxhdGl2ZSB0byBzZXh1YWwgcG9wdWxhdGlvbnMuIApgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQp0ZWN0X2h1dHRfbG9jc19hc2V4dWFsIDwtIHRlY3RfbG9jICU+JSAKICBtdXRhdGUobGF0X2xvbmcgPSBzdHJfYyhsYXRpdHVkZSwgbG9uZ2l0dWRlLCBzZXAgPSAiXyIpKSAlPiUgCiAgZmlsdGVyKHJlcHJvZHVjdGl2ZV9tb2RlID09ICJhc2V4dWFsIiwKICAgICAgICAgc3BlY2llcyA9PSAiaHV0dG9uaSIsCiAgICAgICAgICFkdXBsaWNhdGVkKGxhdF9sb25nKSkgJT4lIAogIGRwbHlyOjpzZWxlY3QobG9uZ2l0dWRlLCBsYXRpdHVkZSkKCnRlY3RfaHV0dF9sb2NzX3NleHVhbCA8LSB0ZWN0X2xvYyAlPiUgCiAgbXV0YXRlKGxhdF9sb25nID0gc3RyX2MobGF0aXR1ZGUsIGxvbmdpdHVkZSwgc2VwID0gIl8iKSkgJT4lIAogIGZpbHRlcihyZXByb2R1Y3RpdmVfbW9kZSA9PSAic2V4dWFsIiwKICAgICAgICAgc3BlY2llcyA9PSAiaHV0dG9uaSIsCiAgICAgICAgICFkdXBsaWNhdGVkKGxhdF9sb25nKSkgJT4lIAogIGRwbHlyOjpzZWxlY3QobG9uZ2l0dWRlLCBsYXRpdHVkZSkKCnByZWNpcF9hc2V4dWFsX3RlY3RfaHV0dCA8LSByYXN0ZXI6OmV4dHJhY3QocHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQsIHRlY3RfaHV0dF9sb2NzX2FzZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJwcmVjaXBfc3RhYmlsaXR5X3NjYWxlZCIpICU+JSAKICBtdXRhdGUocmVwcm9kdWN0aXZlX21vZGUgPSAiYXNleHVhbCIpCgpwcmVjaXBfc2V4dWFsX3RlY3RfaHV0dCA8LSByYXN0ZXI6OmV4dHJhY3QocHJlY2lwX3N0YWJpbGl0eV9zY2FsZWQsIHRlY3RfaHV0dF9sb2NzX3NleHVhbCkgJT4lIAogIGVuZnJhbWUobmFtZSA9IE5VTEwsIHZhbHVlID0gInByZWNpcF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJzZXh1YWwiKQoKcHJlY2lwX2RmX3RlY3RfaHV0dCA8LSBiaW5kX3Jvd3MocHJlY2lwX2FzZXh1YWxfdGVjdF9odXR0LCBwcmVjaXBfc2V4dWFsX3RlY3RfaHV0dCkKCnJlYWRyOjp3cml0ZV9jc3YocHJlY2lwX2RmX3RlY3RfaHV0dCwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9odXR0X3ByZWNpcF9zdGFiaWxpdHlfZGYuY3N2IikpCgp0ZWN0X2h1dHRfcHJlY2lwX3N0YWJpbGl0eV9wbG90IDwtIGdncGxvdChkYXRhID0gcHJlY2lwX2RmX3RlY3RfaHV0dCwgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IHByZWNpcF9zdGFiaWxpdHlfc2NhbGVkLCBjb2xvciA9IHJlcHJvZHVjdGl2ZV9tb2RlKSkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IDAuNSwgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gInRyYW5zcGFyZW50IikgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBhbHBoYSA9IDAuNikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAibWFnbWEiKSArCiAgdGhlbWVfZGFyaygpCgp0ZWN0X2h1dHRfcHJlY2lwX3N0YWJpbGl0eV9wbG90CgpnZ3NhdmUoInRlY3RfaHV0dF9wcmVjaXBfc3RhYmlsaXR5LnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9odXR0X3ByZWNpcF9zdGFiaWxpdHlfcGxvdCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKdGVtcF9hc2V4dWFsX3RlY3RfaHV0dCA8LSByYXN0ZXI6OmV4dHJhY3QodGVtcF9zdGFiaWxpdHlfc2NhbGVkLCB0ZWN0X2h1dHRfbG9jc19hc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAidGVtcF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCnRlbXBfc2V4dWFsX3RlY3RfaHV0dCA8LSByYXN0ZXI6OmV4dHJhY3QodGVtcF9zdGFiaWxpdHlfc2NhbGVkLCB0ZWN0X2h1dHRfbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJ0ZW1wX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgp0ZW1wX2RmX3RlY3RfaHV0dCA8LSBiaW5kX3Jvd3ModGVtcF9hc2V4dWFsX3RlY3RfaHV0dCwgdGVtcF9zZXh1YWxfdGVjdF9odXR0KQoKcmVhZHI6OndyaXRlX2Nzdih0ZW1wX2RmX3RlY3RfaHV0dCwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9odXR0X3RlbXBfc3RhYmlsaXR5X2RmLmNzdiIpKQoKdGVjdF9odXR0X3RlbXBfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSB0ZW1wX2RmX3RlY3RfaHV0dCwgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IHRlbXBfc3RhYmlsaXR5X3NjYWxlZCwgY29sb3IgPSByZXByb2R1Y3RpdmVfbW9kZSkpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjUsIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJ0cmFuc3BhcmVudCIpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMiwgYWxwaGEgPSAwLjYpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uID0gIm1hZ21hIikgKwogIHRoZW1lX2RhcmsoKQoKdGVjdF9odXR0X3RlbXBfc3RhYmlsaXR5X3Bsb3QKCmdnc2F2ZSgidGVjdF9odXR0X3ByZWNpcF9zdGFiaWxpdHkucG5nIiwKICAgICAgIHBsb3QgPSB0ZWN0X2h1dHRfdGVtcF9zdGFiaWxpdHlfcGxvdCwKICAgICAgIGRldmljZSA9ICJwbmciLAogICAgICAgcGF0aCA9IHBsb3RfcGF0aCwKICAgICAgIGRwaSA9ICJyZXRpbmEiKQoKb3ZlcmFsbF9hc2V4dWFsX3RlY3RfaHV0dCA8LSByYXN0ZXI6OmV4dHJhY3Qob3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkLCB0ZWN0X2h1dHRfbG9jc19hc2V4dWFsKSAlPiUgCiAgZW5mcmFtZShuYW1lID0gTlVMTCwgdmFsdWUgPSAib3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkIikgJT4lIAogIG11dGF0ZShyZXByb2R1Y3RpdmVfbW9kZSA9ICJhc2V4dWFsIikKCm92ZXJhbGxfc2V4dWFsX3RlY3RfaHV0dCA8LSByYXN0ZXI6OmV4dHJhY3Qob3ZlcmFsbF9zdGFiaWxpdHlfc2NhbGVkLCB0ZWN0X2h1dHRfbG9jc19zZXh1YWwpICU+JSAKICBlbmZyYW1lKG5hbWUgPSBOVUxMLCB2YWx1ZSA9ICJvdmVyYWxsX3N0YWJpbGl0eV9zY2FsZWQiKSAlPiUgCiAgbXV0YXRlKHJlcHJvZHVjdGl2ZV9tb2RlID0gInNleHVhbCIpCgpvdmVyYWxsX2RmX3RlY3RfaHV0dCA8LSBiaW5kX3Jvd3Mob3ZlcmFsbF9hc2V4dWFsX3RlY3RfaHV0dCwgb3ZlcmFsbF9zZXh1YWxfdGVjdF9odXR0KQoKcmVhZHI6OndyaXRlX2NzdihvdmVyYWxsX2RmX3RlY3RfaHV0dCwgCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHNwcmVhZF9wYXRoLCAidGVjdF9odXR0X292ZXJhbGxfc3RhYmlsaXR5X2RmLmNzdiIpKQoKdGVjdF9odXR0X292ZXJhbGxfc3RhYmlsaXR5X3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBvdmVyYWxsX2RmX3RlY3RfaHV0dCwgYWVzKHggPSByZXByb2R1Y3RpdmVfbW9kZSwgeSA9IG92ZXJhbGxfc3RhYmlsaXR5X3NjYWxlZCwgY29sb3IgPSByZXByb2R1Y3RpdmVfbW9kZSkpICsKICBnZW9tX2JveHBsb3Qod2lkdGggPSAwLjUsIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9ICJ0cmFuc3BhcmVudCIpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMiwgYWxwaGEgPSAwLjYpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uID0gIm1hZ21hIikgKwogIHRoZW1lX2RhcmsoKQoKdGVjdF9odXR0X292ZXJhbGxfc3RhYmlsaXR5X3Bsb3QKCmdnc2F2ZSgidGVjdF9odXR0X292ZXJhbGxfc3RhYmlsaXR5LnBuZyIsCiAgICAgICBwbG90ID0gdGVjdF9odXR0X292ZXJhbGxfc3RhYmlsaXR5X3Bsb3QsCiAgICAgICBkZXZpY2UgPSAicG5nIiwKICAgICAgIHBhdGggPSBwbG90X3BhdGgsCiAgICAgICBkcGkgPSAicmV0aW5hIikKYGBgCgpQdXQgYWxsIG91dHB1dCBpbnRvIHNwZWNpZXMtc3BlY2lmaWMgc3ViZm9sZGVycy4KYGBge3IgcmVzdWx0cz0iaGlkZSJ9CnRlY3RfaHV0dF9vdXRfaW50X3BhdGggPC0gZmlsZS5wYXRoKGludGVyYWN0aXZlX3BhdGgsICJ0ZWN0YXJjaHVzX2h1dHRvbmkiKQp0ZWN0X2h1dHRfb3V0X3Bsb3RfcGF0aCA8LSBmaWxlLnBhdGgocGxvdF9wYXRoLCAidGVjdGFyY2h1c19odXR0b25pIikKdGVjdF9odXR0X291dF9zcHJlYWRfcGF0aCA8LSBmaWxlLnBhdGgoc3ByZWFkX3BhdGgsICJ0ZWN0YXJjaHVzX2h1dHRvbmkiKQp0ZWN0X2h1dHRfb3V0X29ial9wYXRoIDwtIGZpbGUucGF0aChvYmpfcGF0aCwgInRlY3RhcmNodXNfaHV0dG9uaSIpCgojIG1vdmUgaW50ZXJhY3RpdmUKbW92ZV90b19zcGVjaWVzKGluX3BhdGggPSBpbnRlcmFjdGl2ZV9wYXRoLAogICAgICAgICAgICAgICAgb3V0X3BhdGggPSB0ZWN0X2h1dHRfb3V0X2ludF9wYXRoLAogICAgICAgICAgICAgICAgcGF0dGVybiA9ICJ0ZWN0X2h1dHQiKQojIG1vdmUgcGxvdHMKbW92ZV90b19zcGVjaWVzKGluX3BhdGggPSBwbG90X3BhdGgsCiAgICAgICAgICAgICAgICBvdXRfcGF0aCA9IHRlY3RfaHV0dF9vdXRfcGxvdF9wYXRoLAogICAgICAgICAgICAgICAgcGF0dGVybiA9ICJ0ZWN0X2h1dHQiKQoKIyBtb3ZlIHNwcmVhZHNoZWV0cwptb3ZlX3RvX3NwZWNpZXMoaW5fcGF0aCA9IHNwcmVhZF9wYXRoLAogICAgICAgICAgICAgICAgb3V0X3BhdGggPSB0ZWN0X2h1dHRfb3V0X3NwcmVhZF9wYXRoLAogICAgICAgICAgICAgICAgcGF0dGVybiA9ICJ0ZWN0X2h1dHQiKQoKIyBtb3ZlIG9iamVjdHMKbW92ZV90b19zcGVjaWVzKGluX3BhdGggPSBvYmpfcGF0aCwKICAgICAgICAgICAgICAgIG91dF9wYXRoID0gdGVjdF9odXR0X291dF9vYmpfcGF0aCwKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSAidGVjdF9odXR0IikKYGBgCgojIyMgVGVwYWtpcGhhc21hCk5vdGhpbmcuIE9ubHkgb25lIGxvY2FsaXR5LgoKIyMgQ29udmVuaWVuY2Ugc2NyaXB0cwoqVGhlc2Ugc2NyaXB0cyBhcmVuJ3QgY3J1Y2lhbCBmb3IgcmVwcm9kdWNpbmcgdGhpcyBhbmFseXNpcywgYnV0IHdlcmUgaGVscGZ1bCBmb3IgdmFyaW91cyByZWFzb25zLiBTb21lIG9mIHRoZXNlIGhhdmUgaGFyZC1jb2RlZCBwYXRocyBhbmQgc3VjaCwgc28gbm8gZ3VhcmFudGVlcyBmb3IgdXNlIHJpZ2h0IG91dCBvZiB0aGUgYm94LioKCgpUaGlzIHdhcyBhIHNjcmlwdCBJIHVzZWQgdG8gdGFrZSBmdWxsIGNoZWxzYSBmaWxlcywgY3JvcCB0aGVtIHRvIE5ldyBaZWFsYW5kIGV4dGVudCwgYW5kIHdyaXRlIHRoZW0gdG8gYSBmaWxlIHdpdGggbXkgcGVyc29uYWwgY29tcHV0ZXIuIEkgZG9uJ3QgaGF2ZSBtdWNoIG1lbW9yeSwgc28gdW56aXBwaW5nIHRvIGEgdGVtcG9yYXJ5IGRpcmVjdG9yeSwgdGhlbiBkZWxldGluZyB0aGUgZGlyZWN0b3J5IHRvIGZyZWUgdXAgc3BhY2UgZm9yIHRoZSBsYXJnZSBmaWxlcyB3b3JrZWQuIApgYGB7ciBldmFsPUZBTFNFfQojIyBnZXQgY2hlbHNhIGRhdGEKY2hlbHNhX2ZvbGRlciA8LSAiL1VzZXJzL2Nvbm5vcmZyZW5jaC9Ecm9wYm94L09sZF9NYWMvY2xpbWF0ZS1kYXRhL2NoZWxzYV8zMHNfYmlvIgp6aXBfZmlsZXMgPC0gbGlzdC5maWxlcyhjaGVsc2FfZm9sZGVyLCBmdWxsLm5hbWVzID0gVFJVRSkKCiMgdXNpbmcgdGhlIFVuYXJjaGl2ZXIgY29tbWFuZGxpbmUgdG9vbHMgZm9yIE1hYyB0byB1bnppcCB0aGUgN3ppcCBjaGVsc2EgbGF5ZXJzLiBSZWd1bGFyIHVuemlwKCkgZG9lcyBub3Qgd29yayB3aXRoIDd6IHppcHBlZCBmaWxlcwpmb3IgKGZpbGUgaW4gemlwX2ZpbGVzKSB7CiAgIyBzZXQgdGVtcCBkaXJlY3RvcnkKICB0ZW1wZCA8LSB0ZW1wZGlyKCkKICBzeXN0ZW0ocGFzdGUoInVuYXIiLCBmaWxlLCAiLW8iLCB0ZW1wZCkpCiAgciA8LSByYXN0ZXIobGlzdC5maWxlcyh0ZW1wZCwgcGF0dGVybiA9ICIqLnRpZiIsIGZ1bGwubmFtZXMgPSBUUlVFKSkgJT4lCiAgICBjcm9wKGV4dGVudCgxNjYsIDE3OSwgLTQ4LCAtMzQpKQogIHdyaXRlUmFzdGVyKHIsIGZpbGVuYW1lID0gcGFzdGUwKCJ+L0Rlc2t0b3AvIiwgbGlzdC5maWxlcyh0ZW1wZCwgcGF0dGVybiA9ICIqLnRpZiIpKSwgZm9ybWF0ID0gIkdUaWZmIikKICB1bmxpbmsodGVtcGQsIHJlY3Vyc2l2ZSA9IFRSVUUpCn0KYGBgCgo=